内容简介:在前文系统提供的底层能力的功能模块例如网络连接、文件IO等都会使用到大多数情况下,这些高级
在前文 《为何你还不懂得如何使用 Python 协程
》
中提到协程是通过 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 asyncio import time def 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 asyncio import datetime def 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.0 loop.call_soon(display_date, end_time, loop) # 一直运行,等待stop的调用 try: loop.run_forever() finally: loop.close() 复制代码
执行结果打印5秒时间点
2019-05-09 22:34:47.885412 2019-05-09 22:34:48.887513 2019-05-09 22:34:49.889396 2019-05-09 22:34:50.894316 2019-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 asyncio import selectors selector = selectors.SelectSelector() loop = asyncio.SelectorEventLoop(selector) asyncio.set_event_loop(loop) 复制代码
ProactorEventLoop
这个是 Windows
平台专有的实现
import asyncio import sys if sys.platform == 'win32': loop = asyncio.ProactorEventLoop() asyncio.set_event_loop(loop) 复制代码
0x01 总结
事件循环是 asyncio
的核心, asncio
模块的很多高级接口是通过封装 Event Loop
对象来实现的。它提供了执行异步任务、事件回调、执行网络IO操作和运行子进程的能力。
本文是通过官方文档对事件循环的概念和它的常见API做了一个大概的了解。作为《前文》的补充
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 了解Vert.x:事件循环
- 深入了解nodejs的事件循环机制
- 深入了解JavaScript 中的For循环之详解
- 从event loop到async await来了解事件循环机制
- 深入了解Flutter的isolate(1) ---- 事件循环(event loop)及代码运行顺序
- 008.Python循环for循环
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Masterminds of Programming
Federico Biancuzzi、Chromatic / O'Reilly Media / 2009-03-27 / USD 39.99
Description Masterminds of Programming features exclusive interviews with the creators of several historic and highly influential programming languages. Think along with Adin D. Falkoff (APL), Jame......一起来看看 《Masterminds of Programming》 这本书的介绍吧!
JS 压缩/解压工具
在线压缩/解压 JS 代码
JSON 在线解析
在线 JSON 格式化工具