Skip to main content

18.5.2. 事件循环

18.5.2.1. 事件循环函数

以下函数是访问全局策略方法的便捷快捷方式。注意,这提供对默认策略的访问,除非通过在进程的执行中较早调用 set_event_loop_policy() 来设置替代策略。

asyncio.get_event_loop()

相当于调用 get_event_loop_policy().get_event_loop()

asyncio.set_event_loop(loop)

相当于调用 get_event_loop_policy().set_event_loop(loop)

asyncio.new_event_loop()

相当于调用 get_event_loop_policy().new_event_loop()

18.5.2.2. 可用的事件循环

asyncio当前提供了两种事件循环的实现:SelectorEventLoopProactorEventLoop

class asyncio.SelectorEventLoop

基于 selectors 模块的事件循环。 AbstractEventLoop 子类。

使用平台上最高效的选择器。

在Windows上,仅支持套接字(例如:不支持管道):请参阅 MSDN文档的select

class asyncio.ProactorEventLoop

使用“I/O完成端口”(也称为IOCP)的Windows的Proactor事件循环。 AbstractEventLoop 的子类。

可用性:Windows。

在Windows上使用 ProactorEventLoop 的示例:

import asyncio, sys

if sys.platform == 'win32':
    loop = asyncio.ProactorEventLoop()
    asyncio.set_event_loop(loop)

18.5.2.3. 平台支持

asyncio 模块设计为便携式,但每个平台仍然有微妙的差异,可能不支持所有 asyncio 功能。

18.5.2.3.1. 视窗

Windows事件循环的常见限制:

SelectorEventLoop 具体限值:

ProactorEventLoop 具体限值:

Windows上的单调时钟的分辨率通常约为15.6毫秒。最佳分辨率为0.5毫秒。分辨率取决于硬件(HPET 的可用性)和Windows配置。见 asyncio延迟呼叫

在 3.5 版更改: ProactorEventLoop 现在支持SSL。

18.5.2.3.2. Mac OS X

字符设备像PTY只有很好支持自Mavericks(Mac OS 10.9)。它们在Mac OS 10.5及更高版本上不受支持。

在Mac OS 10.6,10.7和10.8上,默认事件循环是使用 selectors.KqueueSelectorSelectorEventLoopselectors.KqueueSelector 不支持这些版本上的字符设备。 SelectorEventLoop 可以与 SelectSelectorPollSelector 一起使用,以支持这些版本的Mac OS X上的字符设备:

import asyncio
import selectors

selector = selectors.SelectSelector()
loop = asyncio.SelectorEventLoop(selector)
asyncio.set_event_loop(loop)

18.5.2.4. 事件循环策略和默认策略

事件循环管理被抽象为 policy 模式,为自定义平台和框架提供最大的灵活性。在进程的整个执行过程中,单个全局策略对象基于调用上下文来管理对进程可用的事件循环。策略是实现 AbstractEventLoopPolicy 接口的对象。

对于 asyncio 的大多数用户,策略从不必显式地处理,因为默认全局策略是足够的。

默认策略将上下文定义为当前线程,并且管理与 asyncio 交互的每个线程的事件循环。模块级函数 get_event_loop()set_event_loop() 提供对由默认策略管理的事件循环的方便访问。

18.5.2.5. 事件循环策略接口

事件循环策略必须实现以下接口:

class asyncio.AbstractEventLoopPolicy

事件循环策略。

get_event_loop()

获取当前上下文的事件循环。

返回实现 AbstractEventLoop 接口的事件循环对象。

在没有为当前上下文设置事件循环且当前策略未指定创建事件循环的情况下引发异常。它永远不会返回 None

set_event_loop(loop)

将当前上下文的事件循环设置为 loop

new_event_loop()

根据此策略的规则创建并返回一个新的事件循环对象。

如果需要将此循环设置为当前上下文的事件循环,则必须显式调用 set_event_loop()

18.5.2.6. 访问全局循环策略

asyncio.get_event_loop_policy()

获取当前事件循环策略。

asyncio.set_event_loop_policy(policy)

设置当前事件循环策略。如果 policyNone,则会还原默认策略。