import threading import time def producer(name): global mantou while True: if psem.acquire(): mutex.acquire() if empty.acquire(): mantou += 1 basket.append(mantou) print('糕点师%s做了第%s个面包,橱窗现有%s个面包' % (name, mantou, len(basket))) full.release() else: print('橱窗放不下了,稍等...') mutex.release() psem.release() else: print('生产者不够了,稍等...') time.sleep(0.3) def consumer(name): while True: if csem.acquire(): mutex.acquire() if full.acquire(): print('消费者%s吃了第%s个面包,橱窗还剩%s个面包' % (name, basket.pop(),len(basket))) empty.release() else: print('面包还没有做好,稍等...') mutex.release() csem.release() else: print('当前消费者过多,稍等...') time.sleep(0.3) mutex = threading.Semaphore(1) # 互斥信号量,同一时间只能有一个线程访问临界资源 psem = threading.Semaphore(5) # 同步信号量,同一时间只能有5个生产者线程工作 csem = threading.Semaphore(5) # 同步信号量,同一时间只能服务5个消费者 empty = threading.Semaphore(5) # 空位信号量 full = threading.Semaphore(0) # 满位信号量 basket = [] # 缓冲池 装面包的橱窗 mantou = 0 # 面包 basket_SIZE=5 def main(): for i in range(5): p = threading.Thread(target=producer, args=(i + 1,)) p.start() for i in range(5): c = threading.Thread(target=consumer, args=(i + 1,)) c.start() if name == 'main': main() 修改此代码使之能成功实现生产者与消费者的模型
时间: 2024-02-17 08:01:34 浏览: 66
在代码中,需要做以下修改:
1. 将全局变量 `mantou` 和 `basket` 声明为 `threading.local()`,这样每个线程都有自己的一份变量副本,避免多个线程同时访问同一变量的竞争问题。
2. 在 `producer` 函数中,每次添加面包到缓冲池时,需要先判断缓冲池是否已满,如果已满则释放 `psem`,等待消费者消费后再重新获取。同理,在 `consumer` 函数中,每次取出面包前需要先判断缓冲池是否为空,如果为空则释放 `csem`,等待生产者生产后再重新获取。
3. 在 `producer` 函数和 `consumer` 函数中,每次访问共享变量前需要先获取 `mutex` 的锁,避免多个线程同时访问同一变量的竞争问题。
修改后的代码如下:
```
import threading
import time
mutex = threading.Semaphore(1) # 互斥信号量,同一时间只能有一个线程访问临界资源
psem = threading.Semaphore(5) # 同步信号量,同一时间只能有5个生产者线程工作
csem = threading.Semaphore(5) # 同步信号量,同一时间只能服务5个消费者
empty = threading.Semaphore(5) # 空位信号量
full = threading.Semaphore(0) # 满位信号量
basket_SIZE = 5 # 缓冲池大小
mantou = threading.local() # 面包数量,每个线程都有自己的一份变量副本
basket = threading.local() # 缓冲池,每个线程都有自己的一份变量副本
def producer(name):
while True:
if psem.acquire():
mutex.acquire()
if empty.acquire():
if not hasattr(basket, 'value'):
basket.value = [] # 第一次使用时初始化
if not hasattr(mantou, 'value'):
mantou.value = 0 # 第一次使用时初始化
mantou.value += 1
basket.value.append(mantou.value)
print('糕点师%s做了第%s个面包,橱窗现有%s个面包' % (name, mantou.value, len(basket.value)))
full.release()
else:
print('橱窗放不下了,稍等...')
psem.release()
mutex.release()
else:
print('生产者不够了,稍等...')
time.sleep(0.3)
def consumer(name):
while True:
if csem.acquire():
mutex.acquire()
if full.acquire():
if not hasattr(basket, 'value'):
basket.value = [] # 第一次使用时初始化
if not hasattr(mantou, 'value'):
mantou.value = 0 # 第一次使用时初始化
print('消费者%s吃了第%s个面包,橱窗还剩%s个面包' % (name, basket.value.pop(0),len(basket.value)))
empty.release()
else:
print('面包还没有做好,稍等...')
csem.release()
mutex.release()
else:
print('当前消费者过多,稍等...')
time.sleep(0.3)
def main():
for i in range(5):
p = threading.Thread(target=producer, args=(i + 1,))
p.start()
for i in range(5):
c = threading.Thread(target=consumer, args=(i + 1,))
c.start()
if __name__ == '__main__':
main()
```
阅读全文