策略?

事件循環(huán)策略是各個(gè)進(jìn)程的全局對象 ,它控制事件循環(huán)的管理。每個(gè)事件循環(huán)都有一個(gè)默認策略,可以使用策略API更改和定制該策略。

策略定義了“上下文”的概念,每個(gè)上下文管理一個(gè)單獨的事件循環(huán)。默認策略將*context*定義為當前線(xiàn)程。

通過(guò)使用自定義事件循環(huán)策略,可以自定義 get_event_loop() 、 set_event_loop()new_event_loop() 函數的行為。

策略對象應該實(shí)現 AbstractEventLoopPolicy 抽象基類(lèi)中定義的API。

獲取和設置策略?

可以使用下面函數獲取和設置當前進(jìn)程的策略:

asyncio.get_event_loop_policy()?

返回當前進(jìn)程域的策略。

asyncio.set_event_loop_policy(policy)?

policy 設置為當前進(jìn)程域策略。

如果 policy 設為 None 將恢復默認策略。

策略對象?

抽象事件循環(huán)策略基類(lèi)定義如下:

class asyncio.AbstractEventLoopPolicy?

異步策略的抽象基類(lèi)。

get_event_loop()?

為當前上下文獲取事件循環(huán)。

返回一個(gè)實(shí)現 AbstractEventLoop 接口的事件循環(huán)對象。

該方法永遠不應返回 None。

在 3.6 版更改.

set_event_loop(loop)?

將當前上下文的事件循環(huán)設置為 loop 。

new_event_loop()?

創(chuàng )建并返回一個(gè)新的事件循環(huán)對象。

該方法永遠不應返回 None。

get_child_watcher()?

獲取子進(jìn)程監視器對象。

返回一個(gè)實(shí)現 AbstractChildWatcher 接口的監視器對象。

該函數僅支持Unix。

set_child_watcher(watcher)?

將當前子進(jìn)程監視器設置為 watcher 。

該函數僅支持Unix。

asyncio附帶下列內置策略:

class asyncio.DefaultEventLoopPolicy?

默認的 asyncio 策略。 在 Unix 上使用 SelectorEventLoop 而在 Windows 上使用 ProactorEventLoop。

不需要手動(dòng)安裝默認策略。asyncio已配置成自動(dòng)使用默認策略。

在 3.8 版更改: 在 Windows 上,現在默認會(huì )使用 ProactorEventLoop。

class asyncio.WindowsSelectorEventLoopPolicy?

一個(gè)使用 SelectorEventLoop 事件循環(huán)實(shí)現的替代事件循環(huán)策略。

可用性: Windows。

class asyncio.WindowsProactorEventLoopPolicy?

使用 ProactorEventLoop 事件循環(huán)實(shí)現的另一種事件循環(huán)策略。

可用性: Windows。

進(jìn)程監視器?

進(jìn)程監視器允許定制事件循環(huán)如何監視Unix子進(jìn)程。具體來(lái)說(shuō),事件循環(huán)需要知道子進(jìn)程何時(shí)退出。

在asyncio中子進(jìn)程由 create_subprocess_exec()loop.subprocess_exec() 函數創(chuàng )建。

asyncio 定義了 AbstractChildWatcher 抽象基類(lèi),子監視器必須要實(shí)現它,并具有四種不同實(shí)現: ThreadedChildWatcher (已配置為默認使用), MultiLoopChildWatcher, SafeChildWatcherFastChildWatcher。

請參閱 子進(jìn)程和線(xiàn)程 部分。

以下兩個(gè)函數可用于自定義子進(jìn)程監視器實(shí)現,它將被asyncio事件循環(huán)使用:

asyncio.get_child_watcher()?

返回當前策略的當前子監視器。

asyncio.set_child_watcher(watcher)?

將當前策略的子監視器設置為 watcher 。watcher 必須實(shí)現 AbstractChildWatcher 基類(lèi)定義的方法。

備注

第三方事件循環(huán)實(shí)現可能不支持自定義子監視器。對于這樣的事件循環(huán),禁止使用 set_child_watcher() 或不起作用。

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

注冊一個(gè)新的子處理回調函數。

安排 callback(pid, returncode, *args) 在進(jìn)程的PID與 pid 相等時(shí)調用。指定另一個(gè)同進(jìn)程的回調函數替換之前的回調處理函數。

回調函數 callback 必須是線(xiàn)程安全。

remove_child_handler(pid)?

刪除進(jìn)程PID與 pid 相等的進(jìn)程的處理函數。

處理函數成功刪除時(shí)返回 True ,沒(méi)有刪除時(shí)返回 False 。

attach_loop(loop)?

給一個(gè)事件循環(huán)綁定監視器。

如果監視器之前已綁定另一個(gè)事件循環(huán),那么在綁定新循環(huán)前會(huì )先解綁原來(lái)的事件循環(huán)。

注意:循環(huán)有可能是 None 。

is_active()?

如果監視器已準備好使用則返回 True。

使用 不活動(dòng)的 當前子監視器生成子進(jìn)程將引發(fā) RuntimeError。

3.8 新版功能.

close()?

關(guān)閉監視器。

必須調用這個(gè)方法以確保相關(guān)資源會(huì )被清理。

class asyncio.ThreadedChildWatcher?

此實(shí)現會(huì )為每個(gè)生成的子進(jìn)程啟動(dòng)一具新的等待線(xiàn)程。

即使是當 asyncio 事件循環(huán)運行在非主 OS 線(xiàn)程上時(shí)它也能可靠地工作。

當處理大量子進(jìn)程時(shí)不存在顯著(zhù)的開(kāi)銷(xiāo) (每次子進(jìn)程結束時(shí)為 O(1)),但當每個(gè)進(jìn)程啟動(dòng)一個(gè)線(xiàn)程時(shí)則需要額外的內存。

此監視器會(huì )默認被使用。

3.8 新版功能.

class asyncio.MultiLoopChildWatcher?

此實(shí)現會(huì )在實(shí)例化時(shí)注冊一個(gè) SIGCHLD 信號處理程序。 這可能會(huì )破壞為 SIGCHLD 信號安裝自定義處理程序的第三方代碼。

此監視器會(huì )在收到 SIGCHLD 信號時(shí)通過(guò)顯式地輪詢(xún)每個(gè)進(jìn)程來(lái)避免干擾其他代碼生成的進(jìn)程。

該監視器一旦被安裝就不會(huì )限制從不同線(xiàn)程運行子進(jìn)程。

該解決方案是安全的,但在處理大量進(jìn)程時(shí)會(huì )有顯著(zhù)的開(kāi)銷(xiāo) (每收到一個(gè) SIGCHLD 時(shí)為 O(n))。

3.8 新版功能.

class asyncio.SafeChildWatcher?

該實(shí)現會(huì )使用主線(xiàn)程中的活動(dòng)事件循環(huán)來(lái)處理 SIGCHLD 信號。 如果主線(xiàn)程沒(méi)有正在運行的事件循環(huán),則其他線(xiàn)程無(wú)法生成子進(jìn)程 (會(huì )引發(fā) RuntimeError)。

此監視器會(huì )在收到 SIGCHLD 信號時(shí)通過(guò)顯式地輪詢(xún)每個(gè)進(jìn)程來(lái)避免干擾其他代碼生成的進(jìn)程。

該解決方案與 MultiLoopChildWatcher 同樣安全并同樣具有 O(N) 復雜度,但需要主線(xiàn)程有正在運行的事件循環(huán)才能工作。

class asyncio.FastChildWatcher?

這種實(shí)現直接調用 os.waitpid(-1) 來(lái)獲取所有已結束的進(jìn)程,可能會(huì )中斷其它代碼洐生進(jìn)程并等待它們結束。

在處理大量子監視器時(shí)沒(méi)有明顯的開(kāi)銷(xiāo)( O(1) 每次子監視器結束)。

該解決方案需要主線(xiàn)程有正在運行的事件循環(huán)才能工作,這與 SafeChildWatcher 一樣。

class asyncio.PidfdChildWatcher?

這個(gè)實(shí)現會(huì )輪詢(xún)處理文件描述符 (pidfds) 以等待子進(jìn)程終結。 在某些方面,PidfdChildWatcher 是一個(gè)“理想的”子進(jìn)程監視器實(shí)現。 它不需要使用信號或線(xiàn)程,不會(huì )介入任何在事件循環(huán)以外發(fā)起的進(jìn)程,并能隨事件循環(huán)發(fā)起的子進(jìn)程數量進(jìn)行線(xiàn)性伸縮。 其主要缺點(diǎn)在于 pidfds 是 Linux 專(zhuān)屬的,并且僅在較近版本的核心(5.3+)上可用。

3.9 新版功能.

自定義策略?

要實(shí)現一個(gè)新的事件循環(huán)策略,建議子類(lèi)化 DefaultEventLoopPolicy 并重寫(xiě)需要定制行為的方法,例如:

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