•生产者消费者问题(英语:Producer-consumer problem),也称有限缓冲问题(英语:Bounded-buffer problem),是一个多线程同步问题的经典案例。
•该问题描述了两个共享固定大小缓冲区的线程——即所谓的“生产者”和“消费者”——在实际运行时会发生的问题。
•生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程。
•消费者也在缓冲区消耗这些数据。
•该问题的关键就是要保证生产者不会在缓冲区满时加入数据,消费者也不会在缓冲区中空时消耗数据。
创建思路:
•创建一个共享区,共享区的容量为10(使用整型count变量模拟)
•2个生产者,每个生产者消耗随机的时间单位生产1件商品并放入共享区(count自增1模拟),当共享区已满,生产者停止放入共享区,线程进入block阻塞状态,等待消费者线程唤醒。
•5个消费者,每个消费者使用随机的时间单位每次从共享区获取1件商品(count自减1模拟),当共享区已空,消费者停止从共享区获取,线程进入block阻塞状态,等待生产者线程唤醒。
代码实现:
import threading #导入多线程模块
import time #导入时间模块
import random #导入随机模块
count = 0 #使用共享区模拟变量
condition = threading.Condition() #创建条件对象
#创建生产者线程类
class Producer(threading.Thread):
def __init__(self, threadName): #构造方法
threading.Thread.__init__(self)
self.threadName = threadName
pass
def run(self):
global count #引用全局变量
while True:
if condition.acquire(): #使用条件对象获取锁并锁定
if count >= 10: # 判断共享变量是否已达到上限
print("共享区已满,生产者Producer线程进入阻塞Block状态,停止放入!")
condition.wait() #当前线程进入阻塞状态
pass
else:
count += 1 #共享变量自增1
msg = time.ctime() + ' ' + self.threadName + '生产了1件商品放入共享区,共享区商品总数: ' + str(count)
print(msg)
condition.notify() #唤醒其消费者线程
pass
condition.release() #解除锁定
time.sleep(random.randrange(10)/5) #随机休眠n秒
class Customer(threading.Thread): #消费者线程类
def __init__(self, threadName): #构造方法
threading.Thread.__init__(self)
self.threadName = threadName
pass
def run(self):
global count #引用全局变量
while True:
if condition.acquire(): #使用条件对象获取锁并锁定
if count < 1: # 判断共享变量是否为空
print("共享区以空,消费者Customer线程进入阻塞Block状态,停止获取!")
condition.wait() #当前线程进入阻塞状态
pass
else:
count -= 1 #共享变量自减1
msg = time.ctime() + ' ' + self.threadName + '消费了一件商品,共享区商品总数: ' + str(count)
print(msg)
condition.notify() #唤醒其消费者线程
pass
condition.release() #解除锁定
time.sleep(random.randrange(10)) #随机休眠n秒
pass
pass
pass
pass
if __name__ == '__main__':
for i in range(2):
p = Producer('[生产者-0' + str(i+1) + ']')
p.start()
pass
for i in range(5):
c = Customer('消费者-' + str(i+1) + ']')
c.start()
运行结果:
Wed Aug 14 08:14:49 2019 [生产者-01]生产了1件商品放入共享区,共享区商品总数: 1
Wed Aug 14 08:14:49 2019 [生产者-02]生产了1件商品放入共享区,共享区商品总数: 2
Wed Aug 14 08:14:49 2019 消费者-1]消费了一件商品,共享区商品总数: 1
Wed Aug 14 08:14:49 2019 消费者-2]消费了一件商品,共享区商品总数: 0
共享区以空,消费者Customer线程进入阻塞Block状态,停止获取!
共享区以空,消费者Customer线程进入阻塞Block状态,停止获取!
共享区以空,消费者Customer线程进入阻塞Block状态,停止获取!
共享区以空,消费者Customer线程进入阻塞Block状态,停止获取!
Wed Aug 14 08:14:49 2019 [生产者-01]生产了1件商品放入共享区,共享区商品总数: 1
Wed Aug 14 08:14:50 2019 [生产者-01]生产了1件商品放入共享区,共享区商品总数: 2
Wed Aug 14 08:14:51 2019 [生产者-02]生产了1件商品放入共享区,共享区商品总数: 3
Wed Aug 14 08:14:51 2019 消费者-3]消费了一件商品,共享区商品总数: 2
Wed Aug 14 08:14:51 2019 消费者-3]消费了一件商品,共享区商品总数: 1
Wed Aug 14 08:14:52 2019 [生产者-01]生产了1件商品放入共享区,共享区商品总数: 2
Wed Aug 14 08:14:52 2019 [生产者-01]生产了1件商品放入共享区,共享区商品总数: 3
Wed Aug 14 08:14:53 2019 [生产者-02]生产了1件商品放入共享区,共享区商品总数: 4
Wed Aug 14 08:14:54 2019 [生产者-01]生产了1件商品放入共享区,共享区商品总数: 5
Wed Aug 14 08:14:54 2019 [生产者-02]生产了1件商品放入共享区,共享区商品总数: 6
Wed Aug 14 08:14:54 2019 消费者-2]消费了一件商品,共享区商品总数: 5
Wed Aug 14 08:14:55 2019 [生产者-02]生产了1件商品放入共享区,共享区商品总数: 6
Wed Aug 14 08:14:55 2019 [生产者-02]生产了1件商品放入共享区,共享区商品总数: 7
Wed Aug 14 08:14:55 2019 [生产者-01]生产了1件商品放入共享区,共享区商品总数: 8
Wed Aug 14 08:14:55 2019 [生产者-02]生产了1件商品放入共享区,共享区商品总数: 9
Wed Aug 14 08:14:57 2019 [生产者-02]生产了1件商品放入共享区,共享区商品总数: 10
共享区已满,生产者Producer线程进入阻塞Block状态,停止放入!
共享区已满,生产者Producer线程进入阻塞Block状态,停止放入!
Wed Aug 14 08:14:57 2019 消费者-5]消费了一件商品,共享区商品总数: 9
Wed Aug 14 08:14:58 2019 消费者-1]消费了一件商品,共享区商品总数: 8
Wed Aug 14 08:14:58 2019 消费者-1]消费了一件商品,共享区商品总数: 7
Wed Aug 14 08:14:58 2019 消费者-2]消费了一件商品,共享区商品总数: 6
Wed Aug 14 08:14:58 2019 [生产者-02]生产了1件商品放入共享区,共享区商品总数: 7
Wed Aug 14 08:14:59 2019 [生产者-01]生产了1件商品放入共享区,共享区商品总数: 8
Wed Aug 14 08:14:59 2019 消费者-4]消费了一件商品,共享区商品总数: 7
Wed Aug 14 08:14:59 2019 [生产者-01]生产了1件商品放入共享区,共享区商品总数: 8
Wed Aug 14 08:14:59 2019 消费者-3]消费了一件商品,共享区商品总数: 7
Wed Aug 14 08:14:59 2019 消费者-3]消费了一件商品,共享区商品总数: 6
Wed Aug 14 08:15:00 2019 [生产者-02]生产了1件商品放入共享区,共享区商品总数: 7
Wed Aug 14 08:15:00 2019 [生产者-02]生产了1件商品放入共享区,共享区商品总数: 8
Wed Aug 14 08:15:00 2019 [生产者-01]生产了1件商品放入共享区,共享区商品总数: 9
......