政策¶
事件循环策略是控制事件循环管理的全局每进程对象。每个事件循环都有一个默认策略,可以使用策略API更改和自定义该策略。
策略定义了 context 并根据上下文管理单独的事件循环。默认策略定义 context 成为当前线程。
通过使用自定义事件循环策略, get_event_loop()
, set_event_loop()
和 new_event_loop()
可以自定义功能。
策略对象应实现在 AbstractEventLoopPolicy
抽象基类。
获取和设置策略¶
以下函数可用于获取和设置当前进程的策略:
- asyncio.get_event_loop_policy()¶
返回当前的进程范围策略。
- asyncio.set_event_loop_policy(policy)¶
将当前进程范围策略设置为 policy .
如果 policy 设置为
None
,将还原默认策略。
策略对象¶
抽象事件循环策略基类定义如下:
- class asyncio.AbstractEventLoopPolicy¶
异步策略的抽象基类。
- get_event_loop()¶
获取当前上下文的事件循环。
返回实现
AbstractEventLoop
接口。此方法不应返回
None
.在 3.6 版更改.
- set_event_loop(loop)¶
将当前上下文的事件循环设置为 loop .
- new_event_loop()¶
创建并返回一个新的事件循环对象。
此方法不应返回
None
.
- get_child_watcher()¶
获取子进程观察程序对象。
返回实现
AbstractChildWatcher
接口。此函数是特定于Unix的。
- set_child_watcher(watcher)¶
将当前子进程观察程序设置为 观察者 .
此函数是特定于Unix的。
异步具有以下内置策略:
- class asyncio.DefaultEventLoopPolicy¶
默认的异步策略。使用
SelectorEventLoop
在UNIX上ProactorEventLoop
在Windows上。不需要手动安装默认策略。Asyncio配置为自动使用默认策略。
在 3.8 版更改: 在Windows上,
ProactorEventLoop
现在默认使用。
- class asyncio.WindowsSelectorEventLoopPolicy¶
使用
SelectorEventLoop
事件循环实现。Availability :Windows。
- class asyncio.WindowsProactorEventLoopPolicy¶
使用
ProactorEventLoop
事件循环实现。Availability :Windows。
过程观察者¶
进程监视程序允许自定义事件循环如何监视UNIX上的子进程。具体来说,事件循环需要知道子进程何时退出。
在Asyncio中,子进程是用 create_subprocess_exec()
和 loop.subprocess_exec()
功能。
Asyncio定义 AbstractChildWatcher
抽象基类,子观察程序应该实现它,并且有四种不同的实现: ThreadedChildWatcher
(默认配置为使用), MultiLoopChildWatcher
, SafeChildWatcher
和 FastChildWatcher
.
也见 Subprocess and Threads 部分。
以下两个函数可用于自定义Asyncio事件循环使用的子进程观察程序实现:
- asyncio.get_child_watcher()¶
返回当前策略的当前子观察程序。
- asyncio.set_child_watcher(watcher)¶
将当前子观察程序设置为 观察者 对于当前策略。 观察者 必须实现在中定义的方法
AbstractChildWatcher
基类。
注解
第三方事件循环实现可能不支持自定义子观察程序。对于此类事件循环,使用 set_child_watcher()
可能被禁止或无效。
- class asyncio.AbstractChildWatcher¶
- add_child_handler(pid, callback, *args)¶
注册新的子处理程序。
安排
callback(pid, returncode, *args)
当pid等于 pid 终止。为同一进程指定另一个回调将替换上一个处理程序。这个 回调 可调用必须是线程安全的。
- remove_child_handler(pid)¶
删除pid等于的进程的处理程序 pid .
函数返回
True
如果已成功删除处理程序,False
如果没有什么可以移除的。
- attach_loop(loop)¶
将观察程序连接到事件循环。
如果观察程序以前附加到事件循环,那么在附加到新循环之前,它首先被分离。
注:回路可以是
None
.
- is_active()¶
返回
True
如果观察者准备好使用。用生成子进程 不活动 当前子观察程序提升
RuntimeError
.3.8 新版功能.
- close()¶
关闭观察者。
必须调用此方法以确保清理基础资源。
- class asyncio.ThreadedChildWatcher¶
此实现为每个子进程生成启动一个新的等待线程。
即使在非主OS线程中运行Asyncio事件循环,它也能可靠地工作。
在处理大量儿童时,没有明显的开销( O(1) 子进程每次终止),但是每个进程启动一个线程需要额外的内存。
默认情况下使用此观察程序。
3.8 新版功能.
- class asyncio.MultiLoopChildWatcher¶
此实现将注册一个
SIGCHLD
实例化时的信号处理程序。,它可能会中断安装自定义处理程序的第三方代码。SIGCHLD
信号。观察程序通过在
SIGCHLD
信号。一旦安装了监视程序,就不限制从不同线程运行子进程。
该解决方案是安全的,但在处理大量进程时会产生很大的开销。( O(n) 每一次
SIGCHLD
收到。3.8 新版功能.
- class asyncio.SafeChildWatcher¶
此实现使用来自主线程的活动事件循环来处理
SIGCHLD
信号。如果主线程没有正在运行的事件循环,则另一个线程无法生成子进程。 (RuntimeError
提高了)。观察程序通过在
SIGCHLD
信号。这个解决方案和
MultiLoopChildWatcher
也有同样的 O(N) 复杂性,但需要在主线程中运行一个事件循环才能工作。
- class asyncio.FastChildWatcher¶
此实现通过调用
os.waitpid(-1)
直接,可能会破坏其他代码生成进程并等待其终止。处理大量子项时没有明显的开销( O(1) 每次子进程终止)。
此解决方案需要在主线程中运行一个事件循环,作为
SafeChildWatcher
.
- class asyncio.PidfdChildWatcher¶
此实现轮询进程文件描述符(pidfd)以等待子进程终止。在某些方面,
PidfdChildWatcher
是一个“金发女郎”儿童观察程序的实现。它不需要信号或线程,不干扰在事件循环外启动的任何进程,并随事件循环启动的子进程数线性扩展。主要的缺点是pidfd是Linux特有的,并且只适用于最新的(5.3+)内核。3.9 新版功能.
定制策略¶
要实现新的事件循环策略,建议子类 DefaultEventLoopPolicy
并重写需要自定义行为的方法,例如:
class MyEventLoopPolicy(asyncio.DefaultEventLoopPolicy):
def get_event_loop(self):
"""Get the event loop.
This may be None or an instance of EventLoop.
"""
loop = super().get_event_loop()
# Do something with loop ...
return loop
asyncio.set_event_loop_policy(MyEventLoopPolicy())