【摘要】上一篇博文介绍了传统的生产者消费者模型,共有三个元素要素(生产者、消费者、缓冲区)。传统的生产者-消费者模型是一个线程写消息,一个线程取消息,通过锁机制控制队列和等待,但一不小心就可能死锁。
这篇博文介绍的基于0库存的生产者消费者模型,是没有缓冲区这个要素,改用协程(yield),生产者生产好后,直接通过yield跳转到消费者开始执行,待消费者执行完毕后,切换回生产者继续生产,效率极高。
代码如下:
import time
def Consumer(name):
"""消费者"""
want_buy = input("请输入购买物品:")
print("[%s]需要购买%s" %(name, want_buy))
while True:
# 将yield后面的need_produce发送给生产者, 生产者获取生产的信息
goodsname = yield want_buy
print("[%s]购买%s成功" %(name, goodsname))
def Prodcder(name):
"""生产者"""
# []生成一个列表, 列表里面是3个生成器(Consumer)
# ()生成一个生成器, 生成器里面是3个生成器(Consumer)
consumers = (Consumer("消费者%s" %(i+1)) for i in range(3))
for consumer in consumers:
# next方法的返回值就是Consumer里面yield后面跟的值;
need_produce = next(consumer)
print("工程师[%s]正在生产%s" %(name, need_produce))
time.sleep(1)
print("工程师[%s]生产%s成功" % (name, need_produce))
# 将生产好的数据发送给消费者
consumer.send(need_produce)
def main():
Prodcder("potizo")
main()
执行效果:
代码执行流程:
-
Producer(“potizo”)
调用Producer这个函数,进入函数体 -
consumers = (Consumer(“消费者%s” %(i+1)) for i in range(3))
得到一个名为consumers的生成器,这个生成器中包含三个生成器 -
for consumer in consumers
通过for循环迭代生成器,依次得到这个三个生成器 -
need_produce = next(consumer)
每得到一个生成器,就用next方法调用这个生成器,进入生成器consumer代码中执行 -
want_buy = input(“请输入购买物品:”)
用want_buy变量接收用户输入的内容
print("[%s]需要购买%s" %(name, want_buy))并打印 -
goodsname = yield want_buy
再继续执行时,遇到yield关键字。这个生成器中的代码停止执行,并将yield关键字后面的内容返回给next调用生成器那一行代码
need_produce = next(consumer) 用need_produce变量接收返回来的值 -
print(“工程师[%s]正在生产%s” %(name, need_produce))
time.sleep(1)
print(“工程师[%s]生产%s成功” % (name, need_produce))
打印上述内容 -
consumer.send(need_produce)
生产好后,将内容通过send方法传入consumer这个生成器,执行consumer生成器中的代码。由于是用send方法,所以将变量need_produce传给生成器中上一个yield之前的变量goodsname,并继续执行后续代码,直至遇到yield关键字。