策略?
事件循環策略是各個進程的全局對象 ,它控制事件循環的管理。每個事件循環都有一個默認策略,可以使用策略API更改和定制該策略。
策略定義了“上下文”的概念,每個上下文管理一個單獨的事件循環。默認策略將*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? 默認asyncio策略。在Unix和Windows平臺上都使用
SelectorEventLoop。不需要手動安裝默認策略。asyncio已配置成自動使用默認策略。
-
class
asyncio.WindowsProactorEventLoopPolicy? 使用
ProactorEventLoop事件循環實現的另一種事件循環策略。可用性: Windows。
進程監視器?
進程監視器允許定制事件循環如何監視Unix子進程。具體來說,事件循環需要知道子進程何時退出。
在asyncio中子進程由 create_subprocess_exec() 和 loop.subprocess_exec() 函數創建。
asyncio定義了 AbstractChildWatcher 抽象基類,必須由子監視器來實現,可以有兩種實現方式:SafeChildWatcher (已配置為默認使用)和 FastChildWatcher 。
請參閱 子進程和線程 部分。
以下兩個函數可用于自定義子進程監視器實現,它將被asyncio事件循環使用:
-
asyncio.get_child_watcher()? 返回當前策略的當前子監視器。
-
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 相等時調用。指定另一個同進程的回調函數替換之前的回調處理函數。回調函數 callback 必須是線程安全。
-
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 loop
asyncio.set_event_loop_policy(MyEventLoopPolicy())
