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 MD5文件生成码
Jan 12 Python
Python 转义字符详细介绍
Mar 21 Python
浅析python递归函数和河内塔问题
Apr 18 Python
Django objects.all()、objects.get()与objects.filter()之间的区别介绍
Jun 12 Python
Python闭包和装饰器用法实例详解
May 22 Python
Python实用工具FuckIt.py介绍
Jul 02 Python
django实现类似触发器的功能
Nov 15 Python
Python OpenCV视频截取并保存实现代码
Nov 30 Python
python pandas移动窗口函数rolling的用法
Feb 29 Python
基于python生成英文版词云图代码实例
May 16 Python
公认8个效率最高的爬虫框架
Jul 28 Python
Python制作动态字符画的源码
Aug 04 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
不用数据库的多用户文件自由上传投票系统(1)
2006/10/09 PHP
php实现文件下载(支持中文文名)
2013/12/04 PHP
30个php操作redis常用方法代码例子
2014/07/05 PHP
根据表格中的某一列进行排序的javascript代码
2013/11/29 Javascript
通过url查找a元素并点击
2014/04/09 Javascript
jquery图片播放浏览插件prettyPhoto使用详解
2014/12/19 Javascript
javascript跨域原因以及解决方案分享
2015/04/08 Javascript
JavaScript数据库TaffyDB用法实例分析
2015/07/27 Javascript
微信小程序 location API实例详解
2016/10/02 Javascript
详解JavaScript树结构
2017/01/09 Javascript
angular2 ng2 @input和@output理解及示例
2017/10/10 Javascript
vue单页应用在页面刷新时保留状态数据的方法
2018/09/21 Javascript
JS Array.from()将伪数组转换成数组的方法示例
2020/03/23 Javascript
Vuex的热更替如何实现
2020/06/05 Javascript
在vue中实现清除echarts上次保留的数据(亲测有效)
2020/09/09 Javascript
[46:20]CHAOS vs Alliacne 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/16 DOTA
python从ftp下载数据保存实例
2013/11/20 Python
解决Python 遍历字典时删除元素报异常的问题
2016/09/11 Python
Python探索之实现一个简单的HTTP服务器
2017/10/28 Python
python+opencv实现动态物体追踪
2018/01/09 Python
python根据文本生成词云图代码实例
2019/11/15 Python
python默认参数调用方法解析
2020/02/09 Python
django实现HttpResponse返回json数据为中文
2020/03/27 Python
python实现飞船游戏的纵向移动
2020/04/24 Python
python中逻辑与或(and、or)和按位与或异或(&、|、^)区别
2020/08/05 Python
意大利包包和行李箱销售网站:Bagaglio.it
2021/03/02 全球购物
.NET常见笔试题集
2012/12/01 面试题
热能动力工程毕业生自荐信
2013/11/07 职场文书
写给老师的感谢信
2015/01/20 职场文书
银行反洗钱宣传活动总结
2015/05/08 职场文书
2015年街道办事处团委工作总结
2015/10/14 职场文书
争做文明公民倡议书
2019/06/24 职场文书
sql查询结果列拼接成逗号分隔的字符串方法
2021/05/25 SQL Server
各国货币符号大全
2022/02/17 杂记
人民币符号
2022/02/17 杂记
win10系统计算机图标怎么调出来?win10调出计算机图标的方法
2022/08/14 数码科技