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实现汉诺塔方法汇总
Jul 25 Python
Python爬虫包 BeautifulSoup  递归抓取实例详解
Jan 28 Python
python实现快速排序的示例(二分法思想)
Mar 12 Python
python中将一个全部为int的list 转化为str的list方法
Apr 09 Python
详解python中的json和字典dict
Jun 22 Python
Python中fnmatch模块的使用详情
Nov 30 Python
Python实现带参数的用户验证功能装饰器示例
Dec 14 Python
python实现两个dict合并与计算操作示例
Jul 01 Python
Django中间件拦截未登录url实例详解
Sep 03 Python
基于Python编写一个计算器程序,实现简单的加减乘除和取余二元运算
Aug 05 Python
Python logging模块原理解析及应用
Aug 13 Python
python获取时间戳的实现示例(10位和13位)
Sep 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
php下通过POST还是GET来传值
2008/06/05 PHP
php实现基于微信公众平台开发SDK(demo)扩展的方法
2014/12/22 PHP
PHP把MSSQL数据导入到MYSQL的方法
2014/12/27 PHP
php实现xml与json之间的相互转换功能实例
2016/07/07 PHP
php中strlen和mb_strlen用法实例分析
2016/11/12 PHP
php图片裁剪函数
2018/10/31 PHP
PHP开发的文字水印,缩略图,图片水印实现类与用法示例
2019/04/12 PHP
用正则表达式 动态创建/增加css style script 兼容IE firefox
2009/03/10 Javascript
在jquery中处理带有命名空间的XML数据
2011/06/13 Javascript
jQuery EasyUI API 中文文档 - ProgressBar 进度条
2011/09/29 Javascript
jQuery列表拖动排列具体实现
2013/11/04 Javascript
JS在可编辑的div中的光标位置插入内容的方法
2014/11/20 Javascript
使用AngularJS实现可伸缩的页面切换的方法
2015/06/19 Javascript
javascript框架设计之种子模块
2015/06/23 Javascript
javascript创建含数字字母的随机字符串方法总结
2016/08/01 Javascript
解析预加载显示图片艺术
2016/12/05 Javascript
nodejs利用http模块实现银行卡所属银行查询和骚扰电话验证示例
2016/12/30 NodeJs
javascript基础练习之翻转字符串与回文
2017/02/20 Javascript
javascript 产生随机数的几种方法总结
2017/09/26 Javascript
js中split()方法得到的数组长度问题
2018/07/19 Javascript
关于Vue项目跨平台运行问题的解决方法
2018/09/18 Javascript
vue-cli 3.0 版本与3.0以下版本在搭建项目时的区别详解
2018/12/11 Javascript
[46:00]Ti4 冒泡赛第二轮LGD vs C9 2
2014/07/14 DOTA
python读取文件名称生成list的方法
2018/04/27 Python
PyCharm 2019.3发布增加了新功能一览
2019/12/08 Python
HTML5之SVG 2D入门1—SVG(可缩放矢量图形)概述
2013/01/30 HTML / CSS
优秀党支部事迹材料
2014/01/14 职场文书
股份合作协议书
2014/09/10 职场文书
2014教师党员自我评议(5篇)
2014/09/20 职场文书
小学班主任经验交流材料
2014/12/16 职场文书
我的长征观后感
2015/06/09 职场文书
运动会100米加油稿
2015/07/21 职场文书
500字作文之周记
2019/12/13 职场文书
FFmpeg视频处理入门教程(新手必看)
2022/01/22 杂记
python获取带有返回值的多线程
2022/05/02 Python
基于Redission的分布式锁实战
2022/08/14 Redis