创建一个storageevent事件_简单了解一下事件循环(Event Loop)

关于我

一个有思想的程序猿,终身学习实践者,目前在一个创业团队任team lead,技术栈涉及Android、Python、Java和Go,这个也是我们团队的主要技术栈。

Github:https://github.com/hylinux1024

微信公众号:终身开发者(angrycode)

1435d9ac92335bb5a48624e97e8e7912.png

0x00 事件循环(Event Loop)

在前文[《为何你还不懂得如何使用Python协程 》](https://juejin.im/post/5ccf0d18e51d453b557dc340) 中提到协程是通过asyncio包中的高级API来启动的。而asyncio模块中的核心就是事件循环(Event Loop)。它可用于执行异步任务、事件回调、执行网络IO操作和运行子进程。官方的文档也是建议开发者应该尽量使用asyncio包提供的高级的API,避免直接使用Event Loop对象中的方法。

系统提供的底层能力的功能模块例如网络连接、文件IO等都会使用到loop。

大多数情况下,这些高级API可以满足众多使用场景,但作为一个有追求的猿类,应该要有一点点探索的精神,看看在asyncio封装之下的Event Loop。

获取Event Loop对象

  • asyncio.get_running_loop()
  • 获取当前系统线程正在使用的loop对象
  • asyncio.get_event_loop()
  • 获取当前正在使用的loop对象。如果当前系统线程还没有loop对象,那么就会创建一个新的loop对象,并使用asyncio.set_event_loop(loop)方法设置到当前系统线程中。
  • asyncio.new_event_loop()
  • 创建一个新的loop对象
  • asyncio.set_event_loop(loop)
  • 将loop设置成系统线程使用的对象

Event Loop对象的常用方法

如果使用类似asyncio.run()这些高级API,以下这些方法,基本上很少会用到,建议通读一下,大概知道loop对象拥有哪些API,了解以下底层的实现细节。

启动和停止

  • loop.run_until_complete(future)
  • future对象执行完成才返回
  • loop.run_forever() 一直运行,直到调用了loop.stop()方法
  • loop.stop()
  • 停止loop对象
  • loop.is_running()
  • 判断loop是否正在运行
  • loop.is_closed()
  • 判断loop是否关闭
  • loop.close()
  • 关闭loop对象
  • coroutine loop.shutdown_asyncgens()
try: loop.run_forever()finally: loop.run_until_complete(loop.shutdown_asyncgens()) loop.close()

回调方法

  • loop.call_soon(callback, *args, context=None)
  • 在事件循环的下一次迭代中执行callback方法,args是方法中的参数
  • loop.call_soon_threadsafe(callback, *args, context=None)
  • 线程安全的call_soon()
iimport asyncioimport timedef hello_world(loop): print('Hello World') time.sleep(3) # 模拟长时间操作 loop.stop()loop = asyncio.get_event_loop()# 使用loop执行 hello_world()loop.call_soon(hello_world, loop)# 会一直阻塞,直到调用了stop方法try: loop.run_forever()finally: loop.close()

可延迟的回调方法

可设置延迟执行的方法

  • loop.call_later(delay, callback, *args, context=None)
  • 延迟delay秒后执行
  • loop.call_at(when, callback, *args, context=None)
  • 在指定时间点执行
  • loop.time()
  • 返回当前时间
import asyncioimport datetimedef display_date(end_time, loop): print(datetime.datetime.now()) if (loop.time() + 1.0) < end_time: # 1秒后执行 loop.call_later(1, display_date, end_time, loop) else: loop.stop()loop = asyncio.get_event_loop()# 执行5秒end_time = loop.time() + 5.0loop.call_soon(display_date, end_time, loop)# 一直运行,等待stop的调用try: loop.run_forever()finally: loop.close()

执行结果打印5秒时间点

2019-05-09 22:34:47.8854122019-05-09 22:34:48.8875132019-05-09 22:34:49.8893962019-05-09 22:34:50.8943162019-05-09 22:34:51.898457

创建Future和Tasks

  • loop.create_future()
  • 创建一个绑定事件循环的future对象
  • loop.create_task(coro)
  • 将coro放入调度,并返回task对象
  • loop.set_task_factory(factory)
  • 设置任务工厂
  • loop.get_task_factory()
  • 返回任务工厂,有可能返回None

创建网络连

coroutine loop.create_connection(protocol_factory, host=None, port=None, *, ssl=None, family=0, proto=0, flags=0, sock=None, local_addr=None, server_hostname=None, ssl_handshake_timeout=None)

指定host、port等参数创建网络连接

coroutine loop.create_datagram_endpoint(protocol_factory, local_addr=None, remote_addr=None, *, family=0, proto=0, flags=0, reuse_address=None, reuse_port=None, allow_broadcast=None, sock=None)

创建UDP连接

coroutine loop.create_unix_connection(protocol_factory, path=None, *, ssl=None, sock=None, server_hostname=None, ssl_handshake_timeout=None)

创建Unix连接

coroutine loop.create_server(protocol_factory, host=None, port=None, *, family=socket.AF_UNSPEC, flags=socket.AI_PASSIVE, sock=None, backlog=100, ssl=None, reuse_address=None, reuse_port=None, ssl_handshake_timeout=None, start_serving=True)

创建TCP服务

coroutine loop.create_unix_server(protocol_factory, path=None, *, sock=None, backlog=100, ssl=None, ssl_handshake_timeout=None, start_serving=True)

创建Unix服务

coroutine loop.connect_accepted_socket(protocol_factory, sock, *, ssl=None, ssl_handshake_timeout=None)

封装已建立的连接,返回元组(transport, protocol)

Event Loop 的实现

asyncio 的事件循环有两种不同的实现:SelectorEventLoop和 ProactorEventLoop,它们的父类是AbstractEventLoop

SelectorEventLoop

这个是asyncio默认使用的Event Loop实现,支持unix和windows平台

import asyncioimport selectorsselector = selectors.SelectSelector()loop = asyncio.SelectorEventLoop(selector)asyncio.set_event_loop(loop)

ProactorEventLoop

这个是Windows平台专有的实现

import asyncioimport sysif sys.platform == 'win32': loop = asyncio.ProactorEventLoop() asyncio.set_event_loop(loop)

0x01 总结

事件循环是asyncio的核心,asncio模块的很多高级接口是通过封装Event Loop对象来实现的。它提供了执行异步任务、事件回调、执行网络IO操作和运行子进程的能力。

本文是通过官方文档对事件循环的概念和它的常见API做了一个大概的了解。作为《前文》的补充

0x02 引用

  1. https://docs.python.org/3/library/asyncio-eventloop.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值