【原创】转载请注明作者Johnthegreat和本文链接

在设计模式中,生产消费者模型占有非常重要的地位,这个模型在现实世界中也有很多有意思的对应场景,比如做包子的人和吃包子的人,当两者速度不匹配时,就需要有一个模型来做匹配(偶合),实现做的包子都会依次消费掉。

import asyncio

class ConsumerProducerModel:
def __init__(self, producer, consumer, queue=asyncio.Queue(), plate_size=6): # the plate holds 6pcs bread
self.queue = queue
self.producer = producer
self.consumer = consumer
self.plate_size = plate_size async def produce_bread(self):
for i in range(self.plate_size):
bread = f"bread {i}"
await asyncio.sleep(0.5) # bread makes faster, 0.5s/pc
await self.queue.put(bread)
print(f'{self.producer} makes {bread}') async def consume_bread(self):
while True:
bread = await self.queue.get()
await asyncio.sleep(1) # eat slower, 1s/pc
print(f'{self.consumer} eats {bread}')
self.queue.task_done() async def main():
queue = asyncio.Queue()
cp1 = ConsumerProducerModel("John", "Grace", queue) # group 1
cp2 = ConsumerProducerModel("Mike", "Lucy", queue) # group 2 producer_1 = cp1.produce_bread()
producer_2 = cp2.produce_bread() consumer_1 = asyncio.ensure_future(cp1.consume_bread())
consumer_2 = asyncio.ensure_future(cp2.consume_bread()) await asyncio.gather(*[producer_1, producer_2])
await queue.join()
consumer_1.cancel()
consumer_2.cancel() if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()

生产消费者模型可以使用多线程和队列来实现,这里选择协程不仅是因为性能不错,而且整个下来逻辑清晰:

1. 先定义初始化的东西,要有个队列,要有生产者,要有消费者,要有装面包的盘子大小;

2. 生产者:根据盘子大小生产出对应的东西(面包),将东西放入盘子(queue);

3. 消费者:从盘子上取东西,每次取东西都是一个任务,每次任务完成,就标记为task_done(调用函数)。在这个层面,一直循环;

4. 主逻辑:实例化生产消费者模型对象,创建生产者协程,创建任务(ensure_future),收集协程结果,等待所有线程结束(join),手动取消两个消费者协程;

5. 运行:首先创建事件循环,然后进入主逻辑,直到完成,关闭循环。

以上,欢迎交流!

最新文章

  1. 数据库执行sql报错Got a packet bigger than 'max_allowed_packet' bytes及重启mysql
  2. ASP.NET网站入侵第三波(fineui系统漏洞,可导致被拖库)
  3. 三分 --- CSU 1548: Design road
  4. 164. Maximum Gap *HARD* -- 无序数组找出排序后连续元素的最大间隔
  5. CF 103E Buying Sets 最大权闭合子图,匹配 难度:4
  6. video 测试
  7. .net单元测试——解除依赖
  8. bc命令详解与实例
  9. MCS-51特殊功能寄存器(SPR)的C51定义
  10. nginx启动
  11. c++ const全局对象是如何处理的
  12. 获取list,有内容就赋值,根据ID显现NAME,没有显现list
  13. Linux-误删apt-get以及把aptitude换回
  14. 一、新建springBoot项目
  15. Python用HTMLTestRunner生成html测试报告
  16. 【JVM】查看JVM加载的类及类加载器的方法
  17. django静态文件
  18. BZOJ4200 NOI2015小园丁与老司机(动态规划+上下界网络流)
  19. Java调用Lua脚本(热载实现)
  20. gitlab上如何添加二进制文件(设计文档)

热门文章

  1. L2-007 家庭房产 (25分) 并查集
  2. Codeforces Round #697 (Div. 3) F. Unusual Matrix (思维,数学)
  3. bnuoj24252 Divide
  4. Codeforces Round #177 (Div. 2) B. Polo the Penguin and Matrix (贪心,数学)
  5. Educational DP Contest G - Longest Path (dp,拓扑排序)
  6. MIT 6.S081 聊聊xv6的文件系统(中)日志层与事务
  7. ansible的Ad-hoc命令
  8. 数位dp【模板 + 老年康复】
  9. vs2019 写入访问权限冲突
  10. 2017.8.11 think list