策略 – – 异步I / O(Python教程)(参考资料)
策略
事件循环策略是一个全局的每个进程对象,用于控制事件循环的管理。每个事件循环都有一个defaultpolicy,可以使用策略API进行更改和自定义.
策略定义了context的概念,并管理每个上下文的单独事件循环。默认策略定义context为当前线程.
使用自定义事件循环策略,get_event_loop()
, set_event_loop()
和new_event_loop()
函数的行为可以自定义.
策略对象应该实现AbstractEventLoopPolicy
抽象基类中定义的API.
获取和设置策略
以下函数可用于获取并设置当前进程的策略:
策略对象
抽象事件循环策略基类定义如下:
- class
asyncio.
AbstractEventLoopPolicy
-
asyncio policies的抽象基类.
set_event_loop
// (loop)-
将当前上下文的事件循环设置为loop.
new_event_loop
()-
创建并返回一个新的事件循环对象.
这个方法永远不应该
None
.
asyncio附带以下内置策略:
- class
asyncio.
DefaultEventLoopPolicy
-
默认的asyncio策略。在Unix和Windows平台上使用
SelectorEventLoop
.无需手动安装默认策略。asynciois配置为自动使用默认策略.
- class
asyncio.
WindowsProactorEventLoopPolicy
-
使用
ProactorEventLoop
事件循环实现可用性:Windows.
加工看守
进程监视器允许自定义事件循环如何监视Unix上的进程。具体来说,事件循环需要在子进程退出时知道.
在asyncio中,使用create_subprocess_exec()
和loop.subprocess_exec()
functions.
asyncio定义AbstractChildWatcher
儿童观察者应该实现的抽象基类,并且有两个区别:SafeChildWatcher
(配置为默认使用)和FastChildWatcher
.
另见子进程和线程section.
以下两个函数可用于自定义asyncio事件循环使用的子进程监视器实现:
asyncio.
set_child_watcher
(watcher)-
将当前儿童观察者设置为当前政策的watcher。watcher必须实现
AbstractChildWatcher
基类.
注意
第三方事件循环实现可能不支持自定义儿童观察者。对于这样的事件循环,使用set_child_watcher()
可能被禁止或无效.
- class
asyncio.
AbstractChildWatcher
-
add_child_handler
(pid, callback, *args)-
注册一个新的子处理程序.
为..作安排
callback(pid, returncode, *args)
当一个PID等于的过程被调用pid终止。指定同一进程的另一个回调替换了previoushandler .callback可调用必须是thread-safe.
remove_child_handler
(pid)-
删除PID等于pid.
该函数返回
True
如果处理程序被成功删除,False
如果没有什么可以移除的话
attach_loop
(loop)-
将观察者带到一个事件循环中
如果观察者先前已连接到事件循环,则在连接到新循环之前首先将其分离.
注意:循环可能是
None
.
close
()-
关闭观察者
必须调用此方法以确保清理底层资源.
- class
asyncio.
SafeChildWatcher
-
此实现通过在
SIGCHLD
信号。这是一个安全的解决方案,但在处理大量进程时会产生很大的开销(O(n)每次
SIGCHLD
收到).默认情况下,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 loopasyncio.set_event_loop_policy(MyEventLoopPolicy())
评论被关闭。