python多進程apply與apply_async的區別


進程池Pool中的apply方法與apply_async的區別

  1. apply方法是阻塞的。
    意思就是等待當前子進程執行完畢后,在執行下一個進程。
    例如:


     
    image.png

    執行結果如下:


     
    image.png

    因為apply是阻塞的,所以進入子進程執行后,等待當前子進程執行完畢,在繼續執行下一個進程。
    例如:
    有三個進程0,1,2。等待子進程0執行完畢后,在執行子進程1,然后子進程2,最后回到主進程執行主進程剩余部分,就像上面的執行結果一樣。
    相當於:
     
    image.png

    這樣好像跟單進程串行執行沒什么區別了。

  2. apply_async 是異步非阻塞的。
    意思就是:不用等待當前進程執行完畢,隨時根據系統調度來進行進程切換。
    例如:


     
    image.png

    執行結果如下:


     
    image.png

    完全沒有等待子進程執行完畢,主進程就已經執行完畢,並退出程序。
為什么會這樣呢?

因為進程的切換是操作系統來控制的,搶占式的切換模式。
我們首先運行的是主進程,cpu運行很快啊,這短短的幾行代碼,完全沒有給操作系統進程切換的機會,主進程就運行完畢了,整個程序結束。子進程完全沒有機會切換到程序就已經結束了。

apply是阻塞式的。

首先主進程開始運行,碰到子進程,操作系統切換到子進程,等待子進程運行結束后,在切換到另外一個子進程,直到所有子進程運行完畢。然后在切換到主進程,運行剩余的部分。

apply_async是異步非阻塞式的。

首先主進程開始運行,碰到子進程后,主進程說:讓我先運行個夠,等到操作系統進行進程切換的時候,在交給子進程運行。以為我們的程序太短,然而還沒等到操作系統進行進程切換,主進程就運行完畢了。

想要子進程執行,就告訴主進程:你等着所有子進程執行完畢后,在運行剩余部分。


 
image.png

畫紅圈的地方及時我們要告訴主進程,你等着所有子進程運行完畢后在運行剩余部分。

注意:close必須在join前調用。

 

 

運行結果如下:
 
image.png

你看,因為apply_async是異步非阻塞式,不用等待當前進程執行完畢,隨時跟進操作系統調度來進行進程切換。
進程0沒有執行完,就切換到進程1開始執行,進程1沒有執行完,就切換到進程2,然后在切換回去。等待所有子進程運行完畢后,最后切換回主進程,執行剩余部分。

異步非阻塞式:

總耗時:3秒多。我們每個子進程休眠3秒,正因為是異步非阻塞式的,不用等待當前運行的子進程執行完畢,隨時根據系統調度來進行進程切換。基本上主進程和三個子進程,四個進程是同時運行的。

阻塞式:

總耗時:9秒多。以為是阻塞式,需要等待當前子進程執行完畢后,在執行下一個子進程。每個子進程休眠3秒,三個子進程休眠9秒。基本上主進程加上子進程,四個進程就相當於在單進程中串行執行的。

python官方建議:廢棄apply,使用apply_async。





免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM