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 相关文章推荐
python3使用urllib示例取googletranslate(谷歌翻译)
Jan 23 Python
python绘图库Matplotlib的安装
Jul 03 Python
Python中获取网页状态码的两个方法
Nov 03 Python
python爬取51job中hr的邮箱
May 14 Python
详解TensorFlow在windows上安装与简单示例
Mar 05 Python
基于Python的Post请求数据爬取的方法详解
Jun 14 Python
python脚本执行CMD命令并返回结果的例子
Aug 14 Python
解决Pytorch 加载训练好的模型 遇到的error问题
Jan 10 Python
pytorch 图像中的数据预处理和批标准化实例
Jan 15 Python
python实现音乐播放和下载小程序功能
Apr 26 Python
python 办公自动化——基于pyqt5和openpyxl统计符合要求的名单
May 25 Python
Django路由层如何获取正确的url
Jul 15 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
从一个不错的留言本弄的mysql数据库操作类
2007/09/02 PHP
PHP 命令行参数详解及应用
2011/05/18 PHP
php获取远程图片体积大小的实例
2013/11/12 PHP
浅谈COOKIE和SESSION区别
2015/07/19 PHP
PHP用函数嵌入网站访问量计数器
2017/10/27 PHP
一个网页标题title的闪动提示效果实现思路
2014/03/22 Javascript
Javascript基础教程之数据类型 (数值 Number)
2015/01/18 Javascript
javascript实现Email邮件显示与删除功能
2015/11/21 Javascript
jQuery获取DOM节点实例分析(2种方式)
2015/12/15 Javascript
RequireJS多页面应用实例分析
2016/06/29 Javascript
JS实现的模仿QQ头像资料卡显示与隐藏效果
2017/04/07 Javascript
js 只比较时间大小的实例
2017/10/26 Javascript
vue综合组件间的通信详解
2017/11/06 Javascript
详解webpack与SPA实践之开发环境搭建
2017/12/18 Javascript
聊聊JS动画库 Velocity.js的使用
2018/03/13 Javascript
Vue使用Canvas绘制图片、矩形、线条、文字,下载图片
2019/04/26 Javascript
你可能从未使用过的11+个JavaScript特性(小结)
2020/01/08 Javascript
Vue快速实现通用表单验证的示例代码
2020/01/09 Javascript
Javascript原型链及instanceof原理详解
2020/05/25 Javascript
Python数据结构之Array用法实例
2014/10/09 Python
python Django框架实现自定义表单提交
2016/03/25 Python
python文件的md5加密方法
2016/04/06 Python
在ubuntu16.04中将python3设置为默认的命令写法
2018/10/31 Python
对pandas中时间窗函数rolling的使用详解
2018/11/28 Python
Python3 venv搭建轻量级虚拟环境的步骤(图文)
2019/08/09 Python
python对Excel按条件进行内容补充(推荐)
2019/11/24 Python
tensorflow之变量初始化(tf.Variable)使用详解
2020/02/06 Python
Windows下Anaconda安装、换源与更新的方法
2020/04/17 Python
详解Python流程控制语句
2020/10/28 Python
戴森西班牙官网:Dyson西班牙
2020/02/04 全球购物
澳洲CFL商城:CHEMIST FOR LESS(中文)
2021/02/28 全球购物
民生工程实施方案
2014/03/22 职场文书
商务考察邀请函模板
2015/02/02 职场文书
趣味运动会新闻稿
2015/07/17 职场文书
西部计划志愿者工作总结
2015/08/11 职场文书