策略 — Python 文档

来自菜鸟教程
Python/docs/3.7/library/asyncio-policy
跳转至:导航、​搜索

政策

事件循环策略是一个全局的每个进程对象,用于控制事件循环的管理。 每个事件循环都有一个默认策略,可以使用策略 API 更改和自定义。

策略定义了 context 的概念,并为每个上下文管理一个单独的事件循环。 默认策略将 context 定义为当前线程。

通过使用自定义事件循环策略,可以自定义 get_event_loop()set_event_loop()new_event_loop() 函数的行为。

策略对象应实现 AbstractEventLoopPolicy 抽象基类中定义的 API。

获取和设置策略

以下函数可用于获取和设置当前进程的策略:

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)

将当前子进程观察者设置为 watcher

这个函数是 Unix 特定的。

asyncio 附带以下内置策略:

class asyncio.DefaultEventLoopPolicy

默认的异步策略。 在 Unix 和 Windows 平台上使用 SelectorEventLoop

无需手动安装默认策略。 asyncio 配置为自动使用默认策略。

class asyncio.WindowsProactorEventLoopPolicy
使用 ProactorEventLoop 事件循环实现的替代事件循环策略。


进程观察者

进程观察器允许自定义事件循环如何监视 Unix 上的子进程。 具体来说,事件循环需要知道子进程何时退出。

在 asyncio 中,子进程是使用 create_subprocess_exec()loop.subprocess_exec() 函数创建的。

asyncio 定义了 AbstractChildWatcher 抽象基类,子观察者应该实现它,并且有两种不同的实现:SafeChildWatcher(配置为默认使用)和 FastChildWatcher

另请参阅 子进程和线程 部分。

以下两个函数可用于自定义 asyncio 事件循环使用的子进程观察器实现:

asyncio.get_child_watcher()
返回当前策略的当前子观察者。
asyncio.set_child_watcher(watcher)
对于当前策略,将当前子观察者设置为 watcherwatcher 必须实现在 AbstractChildWatcher 基类中定义的方法。

笔记

第三方事件循环实现可能不支持自定义子观察者。 对于此类事件循环,使用 set_child_watcher() 可能被禁止或无效。


class asyncio.AbstractChildWatcher
add_child_handler(pid, callback, \*args)

注册一个新的子处理程序。

当PID等于pid的进程终止时,安排调用callback(pid, returncode, *args)。 为同一进程指定另一个回调会替换之前的处理程序。

callback callable 必须是线程安全的。

remove_child_handler(pid)

删除 PID 等于 pid 的进程的处理程序。

如果处理程序成功删除,该函数返回 True,如果没有要删除的内容,则返回 False

attach_loop(loop)

将观察者附加到事件循环。

如果观察者先前附加到事件循环,则在附加到新循环之前首先将其分离。

注意:loop 可能是 None

close()

关闭观察者。

必须调用此方法以确保清理底层资源。

class asyncio.SafeChildWatcher

此实现通过在 SIGCHLD 信号上显式轮询每个进程来避免中断其他代码生成进程。

这是一个安全的解决方案,但在处理大量进程(每次接收到 SIGCHLDO(n))时会产生很大的开销。

asyncio 默认使用这个安全的实现。

class asyncio.FastChildWatcher

此实现通过直接调用 os.waitpid(-1) 来获取每个终止的进程,可能会破坏其他代码生成进程并等待它们的终止。

处理大量子级时没有明显的开销(每次子级终止时 O(1))。


自定义策略

要实现新的事件循环策略,建议子类化 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())