生产者消费者模型
生产者:负责造数据的任务
消费者:接收造出来的数据进行进一步的操作
生产者和消费者之间的中介就叫做缓冲区
为什么使用这个模型?
在并发编程中,如果生产者处理速度很快,而消费者处理速度比较慢,那么生产者就必须等待消费者处理完,才能继续生产数据。同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者。为了解决这个等待的问题,就引入了生产者与消费者模型。让它们之间可以不停的生产和消费。
生产者消费者模式就是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。这个阻塞队列就是用来给生产者和消费者解耦的。
什么时候用这个模型?
程序中出现明显的两类任务,一类任务是负责生产,另外一类任务是负责处理生产的数据的
eg:一个简单的生产者消费者模型
import random
import time
def consumer(name): """消费者"""
print('%s准备买包子...' %(name))
while True:
kind=yield
print('%s购买%s成功...' %(name,kind))
c=consumer('粉条')
next(c)
c.send('茄子包子')
执行顺序:#3,9,10,3,5,6,7,10,11,7,8,7,11
通过debug可以判断
基于缓冲区的生产者消费者模型
import random
import time
#缓冲区列表,存放生产的所有包子,工作方式是队列的工作方式
#(FIFO-first in first out)
#假设缓冲区长度为5,缓冲区就满了,生产者不能生产了
cacheList=[]
cacheListLen=5
def isfull():
#缓冲区满了
return len(cacheList)==5
def consumer(name):
"""消费者"""
print('%s准备买包子...' %(name))
while True:
kind=yield
print('%s购买%s成功...' %(name,kind))
def producer(name):
print('%s厨师正在生产包子...' %(name))
kinds=['酸菜包子','豆沙包子','虾肉包子','青菜包子']
while True:
if not isfull():
#模拟生产数据消耗的时间
time.sleep(random.random())
kind=random.choice(kinds)
print('%s已经生产好%s了...' %(name,kind))
cacheList.append(kind)
else:
print('已经有足够多的包子')
yield
p=producer('粉条')
next(p)
consumers=[consumer('user'+str(i)) for i in range(4)]
for i in consumers:
if not cacheList:
print('目前没有包子')
else:
#如果缓冲区没有满,生产者继续生产包子,从上次停止的地方执行
if not isfull():
next(p)
#从缓冲区拿出包子给消费者
kind=cacheList.pop()
next(i) #执行消费者买包子
i.send(kind) #消费者接收包子