Python多進程、多線程及各自的適用場景


多線程與多進程的應用場景不一樣:
1、線程的創建開銷小、由於GIL的存在,無法真正並行,適合GUI、網絡通信、文件讀寫IO密集型場景;
2、進程的創建開銷大,可以充分利用多個CPU實現並行,適合計算量比較大(比如單個函數執行需要幾分鍾、幾十分鍾以上),且無需IO(簡單地說就是數據已經在內存中,不需要讀取磁盤、不需要網絡通信)的場景。
3、多線程、多進程都不適合的場景:基本不涉及IO或只讀取一次文件這種,且計算量不大,單線程短時間就能結束(一兩秒左右)的情況下,單進程單線程是最好的。

我自己做過對比實驗,這種情況下單進程>多線程>>多進程,實際測試結果:單線程0.98s,4個線程1.03s,4個進程1.6s。

原因在於創建線程、進程的時間額外開銷超過了任務本身的計算時間。

4、實現多線程的方式:threading.Thread()、線程池concurrent.futures.ThreadPoolExecutor
5、實現多進程的方式:multiprocessing.Process、進程池concurrent.futures.ProcessPoolExecutor
6、多線程實現互斥:lock=threading.Lock(),lock.acquire(),訪問共享變量,lock.release(),
7、線程之間的數據共享:多個線程共用一個普通變量作為共享變量就可以,因為多線程共享同一個進程的內存空間。
8、多進程實現互斥:lock=multiprocessing.Manager().Lock();每個進程先lock.acquire(),然后訪問共享變量,再lock.release()。
9、進程之間的數據共享:普通變量不能用作共享變量(因為普通變量屬於宿主進程空間,不屬於新創建的進程們,存在隔離),必須使用multiprocessing.Manager()提供的數據類型。

例如:

list_=Manager().list() #用類似Python的普通list,可以append,但不能直接取值,需要先用list(var)強制轉為普通list
dic_=Manager().dict(), #類似普通的dict
v_=Manager().Value(typecode,value),#單個變量,typecode
array_=Manager().Array(typecode,sequence) #數組

 10、進程之間數據共享的其他方式:pipe、queue


免責聲明!

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



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