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字符串逐字符或逐词反转方法
May 21 Python
Python实现堆排序的方法详解
May 03 Python
11月编程语言排行榜 Python逆袭C#上升到第4
Nov 15 Python
Python实现的将文件每一列写入列表功能示例【测试可用】
Mar 19 Python
对python append 与浅拷贝的实例讲解
May 04 Python
用python处理图片之打开\显示\保存图像的方法
May 04 Python
Python深拷贝与浅拷贝用法实例分析
May 05 Python
python3在同一行内输入n个数并用列表保存的例子
Jul 20 Python
python 多维高斯分布数据生成方式
Dec 09 Python
python GUI库图形界面开发之PyQt5窗口类QMainWindow详细使用方法
Feb 26 Python
教你怎么用Python实现多路径迷宫
Apr 29 Python
Anaconda配置各版本Pytorch的实现
Aug 07 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
第三节 定义一个类 [3]
2006/10/09 PHP
zf框架的数据库追踪器使用示例
2014/03/13 PHP
详解PHP数组赋值方法
2015/11/07 PHP
PHP中的self关键字详解
2019/06/23 PHP
thinkphp5.1框架容器与依赖注入实例分析
2019/07/23 PHP
Javascript this 的一些学习总结
2012/08/02 Javascript
javascript阻止scroll事件多次执行的思路及实现
2013/11/08 Javascript
jqeury-easyui-layout问题解决方法
2014/03/24 Javascript
javascript中数组array及string的方法总结
2014/11/28 Javascript
jQuery操作DOM之获取表单控件的值
2015/01/23 Javascript
纯js代码制作的网页时钟特效【附实例】
2016/03/30 Javascript
JS实现点击事件统计的简单实例
2016/07/10 Javascript
jquery对Json的各种遍历方法总结(必看篇)
2016/09/29 Javascript
Boostrap栅格系统与自己额外定义的媒体查询的冲突问题
2017/02/19 Javascript
用JavaScript和jQuery实现瀑布流
2017/03/19 Javascript
Node解决简单重复问题系列之Excel内容的获取
2018/01/02 Javascript
关于ES6箭头函数中的this问题
2018/02/27 Javascript
基于webpack4.X从零搭建React脚手架的方法步骤
2018/12/23 Javascript
Node.js + express实现上传大文件的方法分析【图片、文本文件】
2019/03/14 Javascript
vue使用showdown并实现代码区域高亮的示例代码
2019/10/17 Javascript
在vue中使用Echarts利用watch做动态数据渲染操作
2020/07/20 Javascript
原生js实现俄罗斯方块
2020/10/20 Javascript
[02:43]DOTA2英雄基础教程 德鲁伊
2014/01/13 DOTA
Python标准库urllib2的一些使用细节总结
2015/03/16 Python
详解python开发环境搭建
2016/12/16 Python
python学生管理系统
2019/01/30 Python
详解Django+uwsgi+Nginx上线最佳实战
2019/03/14 Python
Python3列表List入门知识附实例
2020/02/09 Python
python3正则模块re的使用方法详解
2020/02/11 Python
Python利用PyPDF2库获取PDF文件总页码实例
2020/04/03 Python
结合CSS3的布局新特征谈谈常见布局方法
2016/01/22 HTML / CSS
家长评语和期望
2014/02/10 职场文书
创先争优活动党员公开承诺书
2014/08/29 职场文书
公司内部升职自荐信
2015/03/27 职场文书
2019大学生暑期实习心得总结
2019/08/21 职场文书
陶瓷类经典广告语集锦
2019/10/25 职场文书