python 使用事件对象asyncio.Event来同步协程的操作


Posted in Python onMay 04, 2020

事件对象asyncio.Event是基于threading.Event来实现的。

事件可以一个信号触发多个协程同步工作,

例子如下:

import asyncio
import functools
 
def set_event(event):
  print('setting event in callback')
  event.set()
 
async def coro1(event):
  print('coro1 waiting for event')
  await event.wait()
  print('coro1 triggered')
 
async def coro2(event):
  print('coro2 waiting for event')
  await event.wait()
  print('coro2 triggered')
 
async def main(loop):
  # Create a shared event
  event = asyncio.Event()
  print('event start state: {}'.format(event.is_set()))
 
  loop.call_later(
    0.1, functools.partial(set_event, event)
  )
 
  await asyncio.wait([coro1(event), coro2(event)])
  print('event end state: {}'.format(event.is_set()))
 
event_loop = asyncio.get_event_loop()
try:
  event_loop.run_until_complete(main(event_loop))
finally:
  event_loop.close()

输出如下:

event start state: False
coro2 waiting for event
coro1 waiting for event
setting event in callback
coro2 triggered
coro1 triggered
event end state: True

补充知识: python里使用协程来创建echo客户端

在这个例子里使用asyncio.Protocol来创建一个echo客户端,先导入库asyncio和logging。

接着定义发送的消息MESSAGES。

创建连接服务器的地址SERVER_ADDRESS,接着创建EchoClient类,它是继承asyncio.Protocol。

在这个类的构造函数里,接收两个参数messages和future,

messages是指定要发送的消息数据,future是用来通知socket接收数据完成或者服务器关闭socket的事件通知,以便事件循环知道这个协程已经完成了,就可以退出整个程序。

connection_made函数是当socket连接到服务器时调用,它就立即发送数据给服务器,数据发送完成之后发送了eof标记。

服务器收到数据和标志都回复客户端,客户端data_received函数接收数据,eof_received函数接收结束标记。

connection_lost函数收到服务器断开连接。

这行代码:

client_completed = asyncio.Future()

创建一个协程完成的触发事件。

由于event_loop.create_connection函数只能接收一个参数,需要使用functools.partial来进行多个参数包装成一个参数。

后面通过事件循环来运行协程。

import asyncio
import functools
import logging
import sys
 
MESSAGES = [
  b'This is the message. ',
  b'It will be sent ',
  b'in parts.',
]
SERVER_ADDRESS = ('localhost', 10000)
 
class EchoClient(asyncio.Protocol):
 
  def __init__(self, messages, future):
    super().__init__()
    self.messages = messages
    self.log = logging.getLogger('EchoClient')
    self.f = future
 
  def connection_made(self, transport):
    self.transport = transport
    self.address = transport.get_extra_info('peername')
    self.log.debug(
      'connecting to {} port {}'.format(*self.address)
    )
    # This could be transport.writelines() except that
    # would make it harder to show each part of the message
    # being sent.
    for msg in self.messages:
      transport.write(msg)
      self.log.debug('sending {!r}'.format(msg))
    if transport.can_write_eof():
      transport.write_eof()
 
  def data_received(self, data):
    self.log.debug('received {!r}'.format(data))
 
  def eof_received(self):
    self.log.debug('received EOF')
    self.transport.close()
    if not self.f.done():
      self.f.set_result(True)
 
  def connection_lost(self, exc):
    self.log.debug('server closed connection')
    self.transport.close()
    if not self.f.done():
      self.f.set_result(True)
    super().connection_lost(exc)
 
logging.basicConfig(
  level=logging.DEBUG,
  format='%(name)s: %(message)s',
  stream=sys.stderr,
)
log = logging.getLogger('main')
 
event_loop = asyncio.get_event_loop()
 
client_completed = asyncio.Future()
 
client_factory = functools.partial(
  EchoClient,
  messages=MESSAGES,
  future=client_completed,
)
factory_coroutine = event_loop.create_connection(
  client_factory,
  *SERVER_ADDRESS,
)
 
log.debug('waiting for client to complete')
try:
  event_loop.run_until_complete(factory_coroutine)
  event_loop.run_until_complete(client_completed)
finally:
  log.debug('closing event loop')
  event_loop.close()

以上这篇python 使用事件对象asyncio.Event来同步协程的操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python中的字典遍历备忘
Jan 17 Python
Python工程师面试必备25条知识点
Jan 17 Python
centos 安装python3.6环境并配置虚拟环境的详细教程
Feb 22 Python
10 分钟快速入门 Python3的教程
Jan 29 Python
详解python3安装pillow后报错没有pillow模块以及没有PIL模块问题解决
Apr 17 Python
python requests使用socks5的例子
Jul 25 Python
使用python实现kNN分类算法
Oct 16 Python
在OpenCV里使用特征匹配和单映射变换的代码详解
Oct 23 Python
selenium中get_cookies()和add_cookie()的用法详解
Jan 06 Python
Python selenium爬取微博数据代码实例
May 22 Python
Pycharm在指定目录下生成文件和删除文件的实现
Dec 28 Python
Python结合百度语音识别实现实时翻译软件的实现
Jan 18 Python
在python里使用await关键字来等另外一个协程的实例
May 04 #Python
python 异步async库的使用说明
May 04 #Python
Python插件机制实现详解
May 04 #Python
python3+selenium获取页面加载的所有静态资源文件链接操作
May 04 #Python
解决IDEA 的 plugins 搜不到任何的插件问题
May 04 #Python
python3 sleep 延时秒 毫秒实例
May 04 #Python
Python并发concurrent.futures和asyncio实例
May 04 #Python
You might like
在线竞拍系统的PHP实现框架(一)
2006/10/09 PHP
php通过两层过滤获取留言内容的方法
2016/07/11 PHP
JavaScript让IE浏览器event对象符合W3C DOM标准
2009/11/24 Javascript
Jquery乱码的一次解决过程 图解教程
2010/02/20 Javascript
表单元素与非表单元素刷新区别详细解析
2013/11/06 Javascript
jQuery控制iFrame(实例代码)
2013/11/19 Javascript
javascript基础知识分享之类与函数化
2016/02/13 Javascript
js编写当天简单日历效果【实现代码】
2016/05/03 Javascript
Angular的Bootstrap(引导)和Compiler(编译)机制
2016/06/20 Javascript
AngularJS验证信息框架的封装插件用法【w5cValidator扩展插件】
2016/11/03 Javascript
探索Javascript中this的奥秘
2016/12/11 Javascript
JS获取子、父、兄节点方法小结
2017/08/14 Javascript
es6学习之解构时应该注意的点
2017/08/29 Javascript
vue router仿天猫底部导航栏功能
2017/10/18 Javascript
详解webpack编译多页面vue项目的配置问题
2017/12/11 Javascript
js+SVG实现动态时钟效果
2018/07/14 Javascript
JavaScript实现JSON合并操作示例【递归深度合并】
2018/09/07 Javascript
详解Node.js读写中文内容文件操作
2018/10/10 Javascript
使用 Vue cli 3.0 构建自定义组件库的方法
2019/04/30 Javascript
python正则表达式中的括号匹配问题
2014/12/14 Python
浅谈numpy中linspace的用法 (等差数列创建函数)
2017/06/07 Python
python自定义时钟类、定时任务类
2021/02/22 Python
解决Django中调用keras的模型出现的问题
2019/08/07 Python
python如何基于redis实现ip代理池
2020/01/17 Python
完美解决python针对hdfs上传和下载的问题
2020/06/05 Python
python实现二分类和多分类的ROC曲线教程
2020/06/15 Python
如何判断计算机可能已经中马
2013/03/22 面试题
师范院校学生自荐信范文
2013/12/27 职场文书
质量保证书范本
2014/04/29 职场文书
关于运动会的口号
2014/06/07 职场文书
史上最牛的辞职信
2015/02/28 职场文书
法院个人总结
2015/03/03 职场文书
2015年幼儿园班主任工作总结
2015/05/12 职场文书
JavaScript实现显示和隐藏图片
2021/04/29 Javascript
vue项目多环境配置(.env)的实现
2021/07/21 Vue.js
详解Java七大阻塞队列之SynchronousQueue
2021/09/04 Java/Android