欢迎访问宙启技术站
智能推送

使用Semaphore()实现资源共享和并发控制的实际案例

发布时间:2023-12-24 13:25:04

Semaphore(信号量)是一种实现互斥锁和并发控制的同步机制。它是由计算机科学家Edsger Dijkstra在1965年提出的,可以用于解决资源共享和线程并发访问的问题。

信号量的基本操作包括P操作(申请资源)和V操作(释放资源)。当一个线程想要申请一个资源时,它需要执行P操作;当线程使用完资源后,需要执行V操作来释放资源。

下面通过一个实际案例来说明Semaphore的使用。

案例:餐馆就餐问题

假设一个餐馆有两个厨师和五个座位供顾客就餐。每个厨师可以同时服务一个顾客,但座位只能供一个顾客就餐。因此,我们需要使用Semaphore来实现座位的并发控制和资源共享。

首先,我们创建一个Semaphore对象,初始化座位数量为5:

from threading import Semaphore

seats = Semaphore(5)

接下来,我们创建一个顾客线程和两个厨师线程。每个顾客线程尝试获取一个座位,当没有座位可用时,它会阻塞等待;每个厨师线程会不断地准备食物,并将座位释放出来。

from threading import Thread
import time

def customer(customer_id):
    print('Customer {} arrived at the restaurant.'.format(customer_id))
    seats.acquire()  # P操作,申请一个座位
    print('Customer {} seated and waiting for food.'.format(customer_id))
    time.sleep(1)  # 模拟就餐时间
    seats.release()  # V操作,释放座位
    print('Customer {} finished eating and left the restaurant.'.format(customer_id))

def chef(chef_id):
    while True:
        print('Chef {} is preparing food.'.format(chef_id))
        time.sleep(0.5)  # 模拟做饭时间
        seats.release()  # V操作,释放座位

# 创建顾客和厨师线程
customers = [Thread(target=customer, args=(i,)) for i in range(10)]
chefs = [Thread(target=chef, args=(i,)) for i in range(2)]

# 启动线程
for c in customers:
    c.start()
for c in chefs:
    c.start()

# 等待所有线程完成
for c in customers:
    c.join()
for c in chefs:
    c.join()

在上面的例子中,我们创建了10个顾客线程和2个厨师线程。每个顾客线程并发地尝试获取座位,当座位可用时,就进入就餐状态,并模拟了1秒的就餐时间,然后释放座位。每个厨师线程不断地准备食物并释放座位。

通过执行以上代码,我们可以观察到输出结果。其中,顾客线程会根据座位的可用性来就餐,厨师线程会不断地准备食物并释放座位。这样,我们就实现了餐馆就餐问题的资源共享和并发控制。

在实际应用中,我们可以使用Semaphore来解决各种资源共享和并发控制的问题,比如限制数据库的并发连接数、限制线程池的并发任务数等。Semaphore的灵活性和简单性使得它成为了解决这类问题的有力工具。