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的Tqdm模块的使用
Jan 10 Python
解决python matplotlib imshow无法显示的问题
May 24 Python
python微元法计算函数曲线长度的方法
Nov 08 Python
Pandas Shift函数的基础入门学习笔记
Nov 16 Python
用Python将Excel数据导入到SQL Server的例子
Aug 24 Python
简单了解python协程的相关知识
Aug 31 Python
python pprint模块中print()和pprint()两者的区别
Feb 10 Python
python3实现往mysql中插入datetime类型的数据
Mar 02 Python
python 抓取知乎指定回答下视频的方法
Jul 09 Python
pycharm专业版远程登录服务器的详细教程
Sep 15 Python
python基础详解之if循环语句
Apr 24 Python
python游戏开发Pygame框架
Apr 22 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模板的朋友必看的很多个顶级PHP模板引擎比较分析
2008/05/26 PHP
解析PHP中的unset究竟会不会释放内存
2013/07/18 PHP
再Docker中架设完整的WordPress站点全攻略
2015/07/29 PHP
php连接微软MSSQL(sql server)完全攻略
2016/11/27 PHP
JS动态添加option和删除option(附实例代码)
2013/04/01 Javascript
Jquery解析json数据详解
2013/12/26 Javascript
jQuery控制的不同方向的滑动(向左、向右滑动等)
2014/07/18 Javascript
深入分析Cookie的安全性问题
2015/03/01 Javascript
JavaScript中getUTCMinutes()方法的使用详解
2015/06/10 Javascript
asp.net中oracle 存储过程(图文)
2015/08/12 Javascript
jQuery实现动态表单验证时文本框抖动效果完整实例
2015/08/21 Javascript
Express实现前端后端通信上传图片之存储数据库(mysql)傻瓜式教程(一)
2015/12/10 Javascript
jQuery validate验证插件使用详解
2016/05/11 Javascript
jQuery点击输入框显示验证码图片
2016/05/19 Javascript
JS正则匹配URL网址的方法(可匹配www,http开头的一切网址)
2017/01/06 Javascript
如何选择jQuery版本 1.x? 2.x? 3.x?
2017/04/01 jQuery
vue组件之间通信方式实例总结【8种方式】
2019/02/22 Javascript
JS实现拖拽元素时与另一元素碰撞检测
2020/08/27 Javascript
[01:02:38]DOTA2-DPC中国联赛定级赛 LBZS vs Phoenix BO3第二场 1月10日
2021/03/11 DOTA
[31:47]夜魇凡尔赛茶话会 第三期01:选手知多少
2021/03/11 DOTA
Python正则表达式常用函数总结
2017/06/24 Python
Python生成数字图片代码分享
2017/10/31 Python
Python实现上下班抢个顺风单脚本
2018/02/07 Python
Python 批量读取文件中指定字符的实现
2020/03/06 Python
python爬虫使用scrapy注意事项
2020/11/23 Python
Pycharm创建python文件自动添加日期作者等信息(步骤详解)
2021/02/03 Python
美国葡萄酒网上商店:Martha Stewart Wine Co.
2019/03/17 全球购物
最畅销的视频游戏享受高达90%的折扣:CDKeys
2020/02/10 全球购物
面向对象编程OOP的优点
2013/01/22 面试题
反四风对照检查材料思想汇报
2014/09/16 职场文书
村长反四风问题个人对照检查材料
2014/09/21 职场文书
2014年物业管理工作总结
2014/11/21 职场文书
工作表扬信
2015/01/17 职场文书
家长意见书
2015/06/04 职场文书
2015年数学教研工作总结
2015/07/22 职场文书
Python之matplotlib绘制饼图
2022/04/13 Python