Python  Asyncio模块实现的生产消费者模型的方法


Posted in Python onMarch 01, 2021

asyncio的关键字说明

  • event_loop事件循环:程序开启一个无限循环,把一些函数注册到事件循环上,当满足事件发生的时候,调用相应的协程函数
  • coroutine协程:协程对象,指一个使用async关键字定义的函数,它的调用不会立即执行函数,而是会返回一个协程对象,协程对象需要注册到事件循环,由事件循环调用。
  • task任务:一个协程对象就是一个原生可以挂起的函数,任务则是对协程进一步封装,其中包含了任务的各种状态
  • future:代表将来执行或没有执行的任务结果。它和task上没有本质上的区别
  • async/await关键字:async定义一个协程,await用于挂起阻塞的异步调用接口,在python3.4是使用asyncio.coroutine/yield from

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

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. 运行:首先创建事件循环,然后进入主逻辑,直到完成,关闭循环。

到此这篇关于Python Asyncio模块实现的生产消费者模型的方法的文章就介绍到这了,更多相关Python生产消费者模型内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
零基础写python爬虫之抓取百度贴吧代码分享
Nov 06 Python
使用Python的Treq on Twisted来进行HTTP压力测试
Apr 16 Python
python打印9宫格、25宫格等奇数格 满足横竖斜相加和相等
Jul 19 Python
Django项目中使用JWT的实现代码
Nov 04 Python
python将数组n等分的实例
Dec 02 Python
Python实现线性判别分析(LDA)的MATLAB方式
Dec 09 Python
Python configparser模块配置文件过程解析
Mar 03 Python
Keras构建神经网络踩坑(解决model.predict预测值全为0.0的问题)
Jul 07 Python
matplotlib设置颜色、标记、线条,让你的图像更加丰富(推荐)
Sep 25 Python
python 实现Requests发送带cookies的请求
Feb 08 Python
详解解决jupyter不能使用pytorch的问题
Feb 18 Python
Python爬虫中urllib3与urllib的区别是什么
Jul 21 Python
Python创建自己的加密货币的示例
Mar 01 #Python
python 实现网易邮箱邮件阅读和删除的辅助小脚本
Mar 01 #Python
详解Django中的FBV和CBV对比分析
Mar 01 #Python
Python3压缩和解压缩实现代码
Mar 01 #Python
python re模块常见用法例举
Mar 01 #Python
Python实现简单的2048小游戏
Mar 01 #Python
Python使用Turtle模块绘制国旗的方法示例
Feb 28 #Python
You might like
新52大事件
2020/03/03 欧美动漫
解析PHP的session过期设置
2013/06/29 PHP
PHP微信开发之微信消息自动回复下所遇到的坑
2016/05/09 PHP
功能强大的PHP发邮件类
2016/08/29 PHP
PHP检测数据类型的几种方法(总结)
2017/03/04 PHP
PHP时间处理类操作示例
2018/09/05 PHP
Jquery中dialog属性小记
2010/09/03 Javascript
jQuery解决下拉框select设宽度时IE 6/7/8下option超出显示不全
2013/05/27 Javascript
document.documentElement和document.body区别介绍
2013/09/16 Javascript
js实现非常简单的焦点图切换特效实例
2015/05/07 Javascript
简介可以自动完成UI的AngularJS工具angular-smarty
2015/06/23 Javascript
详解JavaScript数组和字符串中去除重复值的方法
2016/03/07 Javascript
easyui中combotree循环获取父节点至根节点并输出路径实现方法
2016/11/10 Javascript
JQuery统计input和textarea文字输入数量(代码分享)
2016/12/29 Javascript
微信小程序组件 contact-button(客服会话按钮)详解及实例代码
2017/01/10 Javascript
从零学习node.js之模块规范(一)
2017/02/21 Javascript
详解webpack打包vue时提取css
2017/05/26 Javascript
JavaScript基于扩展String实现替换字符串中index处字符的方法
2017/06/13 Javascript
原生js封装添加class,删除class的实例
2017/11/06 Javascript
浅谈Vue.js路由管理器 Vue Router
2018/08/16 Javascript
vue 修改 data 数据问题并实时显示的方法
2018/08/27 Javascript
解决小程序无法触发SESSION问题
2020/02/03 Javascript
JavaScript运行机制实例分析
2020/04/11 Javascript
[03:40]DOTA2亚洲邀请赛小组赛第二日 赛事回顾
2015/01/31 DOTA
详解Django中的过滤器
2015/07/16 Python
python模拟事件触发机制详解
2018/01/19 Python
Python下载网络文本数据到本地内存的四种实现方法示例
2018/02/05 Python
解决tensorflow训练时内存持续增加并占满的问题
2020/01/19 Python
使用Dajngo 通过代码添加xadmin用户和权限(组)
2020/07/03 Python
Stuarts London美国/加拿大:世界领先的独立男装零售商之一
2019/03/18 全球购物
军训自我鉴定
2014/01/22 职场文书
婚前协议书标准版
2014/10/19 职场文书
玩手机检讨书1000字
2014/10/20 职场文书
Vue项目打包、合并及压缩优化网页响应速度
2021/07/07 Vue.js
Go语言grpc和protobuf
2022/04/13 Golang
vue3不同环境下实现配置代理
2022/05/25 Vue.js