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 相关文章推荐
使用wxPython获取系统剪贴板中的数据的教程
May 06 Python
浅析Python基础-流程控制
Mar 18 Python
python访问抓取网页常用命令总结
Apr 11 Python
视觉直观感受若干常用排序算法
Apr 13 Python
Pandas 数据框增、删、改、查、去重、抽样基本操作方法
Apr 12 Python
python的常用模块之collections模块详解
Dec 06 Python
python3 深浅copy对比详解
Aug 12 Python
一篇文章搞定Python操作文件与目录
Aug 13 Python
python中bytes和str类型的区别
Oct 21 Python
基于pytorch padding=SAME的解决方式
Feb 18 Python
Python进阶学习之带你探寻Python类的鼻祖-元类
May 08 Python
Python中的 enumerate和zip详情
May 30 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
日本收入最高的漫画家:海贼王作者版税年收入高达8.45亿元
2020/03/04 日漫
Cannot modify header information错误解决方法
2008/10/08 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(十三)
2014/06/26 PHP
Joomla数据库操作之JFactory::getDBO用法
2016/05/05 PHP
PHP入门教程之数学运算技巧总结
2016/09/11 PHP
yii2安装详细流程
2018/05/23 PHP
laravel-admin 实现给grid的列添加行数序号的方法
2019/10/08 PHP
如何用javascript判断录入的日期是否合法
2007/01/08 Javascript
JavaScript的9个陷阱及评点分析
2008/05/16 Javascript
动态表格Table类的实现
2009/08/26 Javascript
Javascript常考语句107条收集
2010/03/09 Javascript
Ajax异步提交表单数据的说明及方法实例
2013/06/22 Javascript
从数组中随机取x条不重复数据的JS代码
2013/12/24 Javascript
js调试系列 断点与动态调试[基础篇]
2014/06/18 Javascript
JQuery跳出each循环的方法
2015/04/16 Javascript
JS实现带有抽屉效果的产品类网站多级导航菜单代码
2015/09/15 Javascript
让html元素随浏览器的大小自适应垂直居中的实现方法
2016/10/12 Javascript
javascript中call,apply,bind函数用法示例
2016/12/19 Javascript
利用JavaScript实现栈的数据结构示例代码
2017/08/02 Javascript
对angularJs中自定义指令replace的属性详解
2018/10/09 Javascript
JavaScript的变量声明与声明提前用法实例分析
2019/11/26 Javascript
Vue自定义组件的四种方式示例详解
2020/02/28 Javascript
Vue CLI3移动端适配(px2rem或postcss-plugin-px2rem)
2020/04/27 Javascript
Element Input输入框的使用方法
2020/07/26 Javascript
[01:42:49]DOTA2-DPC中国联赛 正赛 iG vs PSG.LGD BO3 第一场 2月26日
2021/03/11 DOTA
python切换hosts文件代码示例
2013/12/31 Python
Python实现加载及解析properties配置文件的方法
2018/03/29 Python
医药大学生求职简历的自我评价
2013/10/17 职场文书
农业资源与环境专业自荐信范文
2013/12/30 职场文书
省级青年文明号申报材料
2014/05/23 职场文书
秋季校运会广播稿100字
2014/09/18 职场文书
小学五年级语文上册教学计划
2015/01/22 职场文书
会计工作能力自我评价
2015/03/05 职场文书
仙境之桥观后感
2015/06/16 职场文书
毕业酒会致辞
2015/07/29 职场文书
Nginx静态压缩和代码压缩提高访问速度详解
2022/05/30 Servers