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 相关文章推荐
python3抓取中文网页的方法
Jul 28 Python
python中使用序列的方法
Aug 03 Python
Python 模拟登陆的两种实现方法
Aug 10 Python
在mac下查找python包存放路径site-packages的实现方法
Nov 06 Python
Django框架首页和登录页分离操作示例
May 28 Python
python 将字符串中的数字相加求和的实现
Jul 18 Python
Python的Tkinter点击按钮触发事件的例子
Jul 19 Python
手把手教你Python yLab的绘制折线图的画法
Oct 23 Python
Python3实现mysql连接和数据框的形成(实例代码)
Jan 17 Python
Python创建空列表的字典2种方法详解
Feb 13 Python
python将dict中的unicode打印成中文实例
May 11 Python
python实现快速文件格式批量转换的方法
Oct 16 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函数
2010/02/16 PHP
Thinkphp中Create方法深入探究
2014/06/16 PHP
PHP采集类snoopy详细介绍(snoopy使用教程)
2014/06/19 PHP
PHP简单装饰器模式实现与用法示例
2017/06/22 PHP
JAVASCRIPT对象及属性
2007/02/13 Javascript
jQuery.validate 常用方法及需要注意的问题
2013/03/20 Javascript
下拉列表select 由左边框移动到右边示例
2013/12/04 Javascript
关闭时刷新父窗口两种方法
2014/05/07 Javascript
jquery库文件略庞大用纯js替换jquery的方法
2014/08/12 Javascript
jQuery选择器全集详解
2014/11/24 Javascript
AngularJS基础学习笔记之表达式
2015/05/10 Javascript
javascript模拟评分控件实现方法
2015/05/13 Javascript
基于jquery实现三级下拉菜单
2016/05/10 Javascript
Bootstrap table表格简单操作
2017/02/07 Javascript
浅谈vue自定义全局组件并通过全局方法 Vue.use() 使用该组件
2017/12/07 Javascript
Angular4.x通过路由守卫进行路由重定向实现根据条件跳转到相应的页面(推荐)
2018/05/10 Javascript
JavaScript使用面向对象实现的拖拽功能详解
2019/06/12 Javascript
使用vue for时为什么要key【推荐】
2019/07/11 Javascript
解决antd datepicker 获取时间默认少8个小时的问题
2020/10/29 Javascript
Python实现获取网站PR及百度权重
2015/01/21 Python
利用Python爬取微博数据生成词云图片实例代码
2017/08/31 Python
Python利用itchat对微信中好友数据实现简单分析的方法
2017/11/21 Python
python 文件查找及内容匹配方法
2018/10/25 Python
Python检查和同步本地时间(北京时间)的实现方法
2018/12/03 Python
python numpy生成等差数列、等比数列的实例
2020/02/25 Python
django跳转页面传参的实现
2020/09/17 Python
Python 实现3种回归模型(Linear Regression,Lasso,Ridge)的示例
2020/10/15 Python
如何用python实现一个HTTP连接池
2021/01/14 Python
中外合拍动画首获奥斯卡提名,“上海出品”《飞奔去月球》能否拿下最终大奖?
2021/03/16 国漫
CSS3教程(7):CSS3嵌入字体
2009/04/02 HTML / CSS
基于HTML5 audio元素播放声音jQuery小插件
2011/05/11 HTML / CSS
二年级学生评语大全
2014/04/23 职场文书
同意迁入证明模板
2014/10/26 职场文书
不尊敬老师的检讨书
2014/12/21 职场文书
何时使用Map来代替普通的JS对象
2021/04/29 Javascript
Vue中插槽slot的使用方法与应用场景详析
2021/06/08 Vue.js