進程池Pool中的apply方法與apply_async的區別
-
apply方法是阻塞的。
意思就是等待當前子進程執行完畢后,在執行下一個進程。
例如:
image.png
執行結果如下:
image.png
因為apply是阻塞的,所以進入子進程執行后,等待當前子進程執行完畢,在繼續執行下一個進程。
例如:
有三個進程0,1,2。等待子進程0執行完畢后,在執行子進程1,然后子進程2,最后回到主進程執行主進程剩余部分,就像上面的執行結果一樣。
相當於:
image.png
這樣好像跟單進程串行執行沒什么區別了。
-
apply_async 是異步非阻塞的。
意思就是:不用等待當前進程執行完畢,隨時根據系統調度來進行進程切換。
例如:
image.png
執行結果如下:
image.png
完全沒有等待子進程執行完畢,主進程就已經執行完畢,並退出程序。
為什么會這樣呢?
因為進程的切換是操作系統來控制的,搶占式的切換模式。
我們首先運行的是主進程,cpu運行很快啊,這短短的幾行代碼,完全沒有給操作系統進程切換的機會,主進程就運行完畢了,整個程序結束。子進程完全沒有機會切換到程序就已經結束了。
apply是阻塞式的。
首先主進程開始運行,碰到子進程,操作系統切換到子進程,等待子進程運行結束后,在切換到另外一個子進程,直到所有子進程運行完畢。然后在切換到主進程,運行剩余的部分。
apply_async是異步非阻塞式的。
首先主進程開始運行,碰到子進程后,主進程說:讓我先運行個夠,等到操作系統進行進程切換的時候,在交給子進程運行。以為我們的程序太短,然而還沒等到操作系統進行進程切換,主進程就運行完畢了。
想要子進程執行,就告訴主進程:你等着所有子進程執行完畢后,在運行剩余部分。

畫紅圈的地方及時我們要告訴主進程,你等着所有子進程運行完畢后在運行剩余部分。
注意:close必須在join前調用。
運行結果如下:

你看,因為apply_async是異步非阻塞式,不用等待當前進程執行完畢,隨時跟進操作系統調度來進行進程切換。
進程0沒有執行完,就切換到進程1開始執行,進程1沒有執行完,就切換到進程2,然后在切換回去。等待所有子進程運行完畢后,最后切換回主進程,執行剩余部分。
異步非阻塞式:
總耗時:3秒多。我們每個子進程休眠3秒,正因為是異步非阻塞式的,不用等待當前運行的子進程執行完畢,隨時根據系統調度來進行進程切換。基本上主進程和三個子進程,四個進程是同時運行的。
阻塞式:
總耗時:9秒多。以為是阻塞式,需要等待當前子進程執行完畢后,在執行下一個子進程。每個子進程休眠3秒,三個子進程休眠9秒。基本上主進程加上子進程,四個進程就相當於在單進程中串行執行的。
python官方建議:廢棄apply,使用apply_async。