政策

事件循环策略是控制事件循环管理的全局每进程对象。每个事件循环都有一个默认策略,可以使用策略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 (默认配置为使用), MultiLoopChildWatcherSafeChildWatcherFastChildWatcher .

也见 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())