使用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的灵活性和简单性使得它成为了解决这类问题的有力工具。
