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调用机器喇叭发出蜂鸣声(Beep)的方法
Mar 23 Python
Python中逗号的三种作用实例分析
Jun 08 Python
python 开发的三种运行模式详细介绍
Jan 18 Python
Python中 传递值 和 传递引用 的区别解析
Feb 22 Python
Python根据指定日期计算后n天,前n天是哪一天的方法
May 29 Python
Python实现处理逆波兰表达式示例
Jul 30 Python
python opencv minAreaRect 生成最小外接矩形的方法
Jul 01 Python
Flask框架模板渲染操作简单示例
Jul 31 Python
Python如何读取文件中图片格式
Jan 13 Python
Pytest框架之fixture的详细使用教程
Apr 07 Python
python中加背景音乐如何操作
Jul 19 Python
Python3爬虫中pyspider的安装步骤
Jul 29 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
正则表达式判断是否存在中文和全角字符和判断包含中文字符串长度
2008/09/27 Javascript
javascript 24小时弹出一次的代码(利用cookies)
2009/09/03 Javascript
利用JQuery+EasyDrag 实现弹出可拖动的Div,同时向Div传值,然后返回Div选中的值
2009/10/24 Javascript
javascript 模拟坦克大战游戏(html5版)附源码下载
2014/04/08 Javascript
js实现表单多按钮提交action的处理方法
2015/10/24 Javascript
全面解析Bootstrap表单使用方法(表单按钮)
2015/11/24 Javascript
Vue服务器渲染Nuxt学习笔记
2018/01/31 Javascript
基于datepicker定义自己的angular时间组件的示例
2018/03/14 Javascript
node.js 模块和其下载资源的镜像设置的方法
2018/09/06 Javascript
axios 封装上传文件的请求方法
2018/09/26 Javascript
详解vue 项目白屏解决方案
2018/10/31 Javascript
Vue实现验证码功能
2019/12/03 Javascript
[01:06:43]完美世界DOTA2联赛PWL S3 PXG vs GXR 第二场 12.19
2020/12/24 DOTA
Python列表计数及插入实例
2014/12/17 Python
浅谈解除装饰器作用(python3新增)
2018/10/15 Python
pycharm 取消默认的右击运行unittest的方法
2018/11/29 Python
Python实现屏幕录制功能的代码
2020/03/02 Python
关于python 的legend图例,参数使用说明
2020/04/17 Python
django 数据库 get_or_create函数返回值是tuple的问题
2020/05/15 Python
Android Q之气泡弹窗的实现示例
2020/06/23 Python
面向新手解析python Beautiful Soup基本用法
2020/07/11 Python
Python面向对象多态实现原理及代码实例
2020/09/16 Python
python实现数据结构中双向循环链表操作的示例
2020/10/09 Python
会走动的图形html5时钟示例
2014/04/27 HTML / CSS
html5实现完美兼容各大浏览器的播放器
2014/12/26 HTML / CSS
HTML5中input[type='date']自定义样式与日历校验功能的实现代码
2017/07/11 HTML / CSS
AmazeUI 加载进度条的实现示例
2020/08/20 HTML / CSS
app内嵌H5 webview 本地缓存问题的解决
2020/10/19 HTML / CSS
澳大利亚设计的优质鞋类和适合澳大利亚生活方式的服装:Rivers
2019/04/23 全球购物
留学推荐信写作指南
2014/01/25 职场文书
会计学专业学生的求职信范文
2014/01/27 职场文书
市场营销管理毕业生自荐信
2014/03/03 职场文书
行政文员实习自我鉴定范文
2014/09/14 职场文书
社区党的群众路线教育实践活动剖析材料
2014/10/09 职场文书
2014年幼儿园保育工作总结
2014/12/02 职场文书
2016读书月活动心得体会
2016/01/14 职场文书