一、什么是生产者消费者模型?
生产者和消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一个存储空间,生产者往存储空间中添加数据,消费者从存储空间中取走数据,当存储空间为空时,消费者阻塞,当存储空间满时,生产者阻塞。
二、为什么要使用生产者和消费者模式?
生产者线程用于生产数据,另一种是消费者线程用于消费数据,为了解耦生产者和消费者的关系(不用一直等待对方的数据)。
通常会采用共享的数据区域,就像是一个仓库,生产者生产数据之后直接放置在共享数据区中,并不需要关心消费者的行为;而消费者只需要从共享数据区中去获取数据,就不再需要关心生产者的行为。
三、python 代码示例
1、通过queue队列实现:
模型:
生产者线程持续生产,最多生产两个,满两个后阻塞,消费者线程每2s 消费一个,消费后生产者线程继续生产直到再次满两个阻塞,
假设消费者消费快于 生产者生产,则消费者阻塞
假设消费者消费慢于 生产者生产,则生产者阻塞
'''
通过队列实现生产者消费者模型
'''
import threading,queue,time
# 创建一个队列,队列最大长度为2
q = queue.Queue(maxsize=2)
def product():
while True:
# 生产者往队列塞数据
q.put('money')
print('生产时间',time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
print('生产了')
def consume():
while True:
time.sleep(2)
# 消费者取出数据
data = q.get()
print('消费时间',time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
print('消费了%s'%data)
t = threading.Thread(target=product)
t1 = threading.Thread(target=consume)
t.start()
t1.start()
2、通过 线程锁 Condition 实现
模型:
生产者生产一个,通知消费者消费
消费者消费完毕,通知生产者再造一个
'''通过条件锁实现生产者消费者模型'''
import threading,time,datetime
# 生产者
lock = threading.Condition()
something = None
def product():
global something
while True:
print('生产者的something=',something)
while something ==None:
print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
time.sleep(5) #生产money 需要5s
lock.acquire()
something = 'money'
print('我生产了money')
lock.notify() #生产完成后立即通知消费者 消费
print('生产者通知消费者已经生产')
lock.wait() #生产者生产完毕后,里层while循环 终止,线程进入外层循环,在wait 处 挂起 ,等待消费者通知
def consumer():
global something
while True:
print('消费者的something=',something)
lock.acquire() # 需要先加锁后面 才能wait()
while something=='money':
something = None # 消费将 something置为 none 里层的while循环 中止 ,
print('money被我消费了')
# time.sleep(2)
lock.notify()
print('消费者通知生产者已经消费')
print('等待通知')
lock.wait() #里层 while 循环结束后,线程执行至wait挂起 等待生产者 生产 后通
p = threading.Thread(target=product)
c = threading.Thread(target=consumer)
p.start()
c.start()