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写xml文件的操作实例
Oct 05 Python
在Python中调用ggplot的三种方法
Apr 08 Python
Python实现控制台输入密码的方法
May 29 Python
Python设计模式编程中Adapter适配器模式的使用实例
Mar 02 Python
Python使用Matplotlib实现雨点图动画效果的方法
Dec 23 Python
python selenium firefox使用详解
Feb 26 Python
python实现异常信息堆栈输出到日志文件
Dec 26 Python
PyTorch的SoftMax交叉熵损失和梯度用法
Jan 15 Python
基于Tensorflow高阶读写教程
Feb 10 Python
django创建超级用户时指定添加其它字段方式
May 14 Python
PyCharm2020.1.2社区版安装,配置及使用教程详解(Windows)
Aug 07 Python
python百行代码实现汉服圈图片爬取
Nov 23 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
基于文本的搜索
2006/10/09 PHP
PHP进程同步代码实例
2015/02/12 PHP
深入讲解PHP Session及如何保持其不过期的方法
2015/08/18 PHP
PHP模板引擎Smarty中变量的使用方法示例
2016/04/11 PHP
php中请求url的五种方法总结
2017/07/13 PHP
PHP crypt()函数的用法讲解
2019/02/15 PHP
JavaScript高级程序设计 扩展--关于动态原型
2010/11/09 Javascript
jquery中ajax学习笔记3
2011/10/16 Javascript
jquery.pagination.js 无刷新分页实现步骤分享
2012/05/23 Javascript
JavaScript中的noscript元素属性位置及作用介绍
2013/04/11 Javascript
CheckBoxList多选样式jquery、C#获取选择项
2013/09/06 Javascript
ExtJS4中的requires使用方法示例介绍
2013/12/03 Javascript
jQuery的选择器中的通配符使用介绍
2014/03/20 Javascript
js实现简单的联动菜单效果
2015/08/19 Javascript
详解JavaScript的回调函数
2015/11/20 Javascript
Bootstrap和Java分页实例第二篇
2016/12/23 Javascript
Node.js如何实现注册邮箱激活功能 (常见)
2017/07/23 Javascript
微信小程序switch组件使用详解
2018/01/31 Javascript
iview Upload组件多个文件上传的示例代码
2018/09/30 Javascript
微信小程序实现左滑修改、删除功能
2020/10/19 Javascript
vue elementui form表单验证的实现
2018/11/11 Javascript
微信小程序制作表格的方法
2019/02/14 Javascript
微信小程序入口场景的问题集合与相关解决方法
2019/06/26 Javascript
[25:59]Newbee vs TNC 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
Django如何实现上传图片功能
2019/08/16 Python
Python爬虫基于lxml解决数据编码乱码问题
2020/07/31 Python
Skyscanner新西兰:全球领先的旅游搜索网站
2019/08/26 全球购物
Java 中访问数据库的步骤?Statement 和PreparedStatement 之间的区别?
2012/06/05 面试题
社区先进事迹材料
2014/05/19 职场文书
欢迎家长标语
2014/10/08 职场文书
优秀团员自我评价
2015/03/10 职场文书
元旦晚会主持词开场白
2015/05/28 职场文书
小学运动会加油词
2015/07/18 职场文书
2016年党风廉政建设承诺书
2016/03/25 职场文书
Python之基础函数案例详解
2021/08/30 Python
深入理解Pytorch微调torchvision模型
2021/11/11 Python