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 上,只有套接字支持 (ex︰ 管道不受支持): 请参阅 MSDN 文档的选择

class asyncio.ProactorEventLoop

Windows 使用"完成端口"aka IOCP 的前摄器事件循环。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. 视窗¶ T0>

Windows事件循环的常见限制:

SelectorEventLoop具体限制:

ProactorEventLoop具体限制:

Windows上的单调时钟的精细度通常约为15.6毫秒。最佳精细度为0.5毫秒。精细度取决于硬件(HPET的可用性)和Windows配置。请参阅asyncio delayed calls

在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上,默认事件循环是SelectorEventLoop,它使用selectors.KqueueSelectorselectors.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. 事件循环策略和默认策略

事件循环管理抽象与 策略 模式,为自定义平台和框架提供最大灵活性。在进程的整个执行过程中,单个全局策略对象基于调用上下文来管理进程可用的事件循环。策略是实现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)

设置当前事件循环策略。如果策略None,则会恢复默认策略。