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检测网页是否有日常链接
Jun 03 Python
Python多线程编程简单介绍
Apr 13 Python
python实现bucket排序算法实例分析
May 04 Python
Python初学时购物车程序练习实例(推荐)
Aug 08 Python
windows下搭建python scrapy爬虫框架步骤
Dec 23 Python
Python类的继承、多态及获取对象信息操作详解
Feb 28 Python
Python中栈、队列与优先级队列的实现方法
Jun 30 Python
简单了解python的内存管理机制
Jul 08 Python
使用Python opencv实现视频与图片的相互转换
Jul 08 Python
关于Flask项目无法使用公网IP访问的解决方式
Nov 19 Python
Python grequests模块使用场景及代码实例
Aug 10 Python
浅谈Python xlwings 读取Excel文件的正确姿势
Feb 26 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多个文件上传到服务器实例
2014/10/29 PHP
9个比较实用的php代码片段
2016/03/15 PHP
jQuery 通过事件委派一次绑定多种事件,以减少事件冗余
2010/06/30 Javascript
jQuery.extend()、jQuery.fn.extend()扩展方法示例详解
2014/05/08 Javascript
Javascript 数组排序详解
2014/10/22 Javascript
jQuery无刷新分页完整实例代码
2015/10/27 Javascript
JQUERY的AJAX请求缓存里的数据问题处理
2016/02/23 Javascript
JS打印组合功能
2016/08/04 Javascript
jQuery的Cookie封装,与PHP交互的简单实现
2016/10/05 Javascript
jQuery弹出div层过2秒自动消失
2016/11/29 Javascript
bootstrap导航、选项卡实现代码
2016/12/28 Javascript
JS基于正则实现数字千分位用逗号分隔的方法
2017/06/16 Javascript
React Native使用Modal自定义分享界面的示例代码
2017/10/31 Javascript
微信小程序显示下拉列表功能【附源码下载】
2017/12/12 Javascript
bootstrap中selectpicker下拉框使用方法实例
2018/03/22 Javascript
jQuery实现的简单拖拽功能示例【测试可用】
2018/08/14 jQuery
微信小程序基于canvas渐变实现的彩虹效果示例
2019/05/03 Javascript
[01:03:03]VP vs Mineski 2018国际邀请赛淘汰赛BO3 第一场 8.22
2018/08/23 DOTA
详解Python中的join()函数的用法
2015/04/07 Python
python实现生命游戏的示例代码(Game of Life)
2018/01/24 Python
Pytorch evaluation每次运行结果不同的解决
2020/01/02 Python
Python实现给PDF添加水印的方法
2021/01/25 Python
StubHub美国:购买或出售您的门票
2019/07/09 全球购物
什么是静态路由,其特点是什么?什么是动态路由,其特点是什么?
2013/07/26 面试题
求职信模版
2013/11/30 职场文书
冰淇淋开店创业计划书
2014/02/01 职场文书
市场策划求职信
2014/08/07 职场文书
信仰心得体会
2014/09/05 职场文书
2014医学院领导干部四风对照检查材料思想汇报
2014/09/16 职场文书
校长师德师风自我剖析材料
2014/09/29 职场文书
初中生散播谣言检讨书
2014/11/17 职场文书
入党转正申请报告
2015/05/15 职场文书
杨善洲观后感
2015/06/04 职场文书
小平您好观后感
2015/06/09 职场文书
王亚平太空授课观后感
2015/06/12 职场文书
JavaScript中10个Reduce常用场景技巧
2022/06/21 Javascript