策略?

事件循環策略是各個進程的全局對象 ,它控制事件循環的管理。每個事件循環都有一個默認策略,可以使用策略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)?

將當前策略的子監視器設置為 watcherwatcher 必須實現 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())