multiprocessing是Python的標準模組,它既可以用來編寫多程式,也可以用來編寫多執行緒。如果是多執行緒的話,用multiprocessing.dummy即可,用法與multiprocessing基本相同,這裡主要介紹多程式的用法,歡迎糾錯。
(一)Multiprocessing介紹
為什麼要使用python多程式?
因為python使用全域性直譯器鎖(GIL),他會將程式中的執行緒序列化,也就是多核cpu實際上並不能達到並行提高速度的目的,而使用多程式則是不受限的,所以實際應用中都是推薦多程式的。
如果每個子程式執行需要消耗的時間非常短(執行+1操作等),這不必使用多程式,因為程式的啟動關閉也會耗費資源。
當然使用多程式往往是用來處理CPU密集型(科學計算)的需求,如果是IO密集型(檔案讀取,爬蟲等)則可以使用多執行緒去處理。
multiprocessing常用元件及功能
建立管理程式模組:
- Process(用於建立程式模組)
- Pool(用於建立管理程式池)
- Queue(用於程式通訊,資源共享)
- Value,Array(用於程式通訊,資源共享)
- Pipe(用於管道通訊)
- Manager(用於資源共享)
同步子程式模組:
- Condition
- Event
- Lock
- RLock
- Semaphore
(二)Multiprocessing程式管理模組
說明:由於篇幅有限,模組具體用法結束請參考每個模組的具體連結。
Process模組
Process模組用來建立子程式,是Multiprocessing核心模組,使用方式與Threading類似,可以實現多程式的建立,啟動,關閉等操作。
具體介紹請參考:Process模組介紹
Pool模組
Pool模組是用來建立管理程式池的,當子程式非常多且需要控制子程式數量時可以使用此模組。
具體介紹請參考:Pool模組介紹
Queue模組
Queue模組用來控制程式安全,與執行緒中的Queue用法一樣。
Pipe模組
Pipe模組用來管道操作。
Manager模組
Manager模組常與Pool模組一起使用,作用是共享資源。
(三)Multiprocessing同步程式模組
Lock模組
作用:當多個程式需要訪問共享資源的時候,Lock可以用來避免訪問的衝突。
具體場景:所有的任務在列印的時候都會向同一個標準輸出(stdout)輸出。這樣輸出的字元會混合在一起,無法閱讀。使用Lock同步,在一個任務輸出完成之後,再允許另一個任務輸出,可以避免多個任務同時向終端輸出。
程式碼實現:
1 2 3 4 5 6 7 8 9 |
from multiprocessing import Process, Lock def l(lock, num): lock.acquire() print "Hello Num: %s" % (num) lock.release() if __name__ == '__main__': lock = Lock() #這個一定要定義為全域性 for num in range(20): Process(target=l, args=(lock, num)).start() #這個類似多執行緒中的threading,但是程式太多了,控制不了。 |
Semaphore模組
作用:用來控制對共享資源的訪問數量,例如池的最大連線數。
Event模組
作用:用來實現程式間同步通訊。
(四)Multiprocessing.dummy多執行緒
Multiprocessing.dummy用法與Multiprocessing用法基本相同,只不過是用來建立多執行緒。
(五)使用Multiprocessing疑問
- 啟動多程式的程式碼一定要放在 if name==”main“: 後面嗎?
解答:windows系統下,想要啟動一個子程式,必須加上if name==”main“:,linux則不需要。
- 父程式中的全域性變數能被子程式共享嗎?
解答:不行,因為每個程式享有獨立的記憶體資料,如果想要共享資源,可以使用Manage類,或者Queue等模組。
- 子程式能結束其他子程式或父程式嗎?如果能,怎麼通過子程式去結束所有程式?
解答:此需求可以稍作修改:所有的子程式都是為了完成一件事情,而當某個子程式完成該事情後,父程式就該結束所有子程式,請問該怎麼做?此時結束所有子程式的操作可以交給父程式去做,因為子程式想要結束另外的子程式比較難實現。
那麼問題就又變成了父程式什麼時候該結束所有程式?
其中一個思路是獲取每個子程式的返回值,一旦有返回True(結束的標記),則立馬結束所有程式;
另外一種思路是使用共享資源,父程式可以一直去判斷這個公共資源,一旦子程式將它改變,則結束所有子程式。(推薦使用前者,因為多程式中不推薦使用資源共享)
- 子程式中還能再建立子程式嗎?
解答:可以,子程式可以再建立程式,執行緒中也可以建立程式。
(六)多程式資源共享問題
多程式中不推薦使用資源共享,如果非要使用,可以參考以下連結。
具體介紹請參考:多程式資源共享問題
(七)獲取子程式返回值問題
多程式中往往會碰到獲取子程式返回值的問題,如果遇到問題可以參考以下連結。
具體介紹請參考:獲取子程式返回值問題
傳送門
【Multiprocessing系列】共享資源
【Multiprocessing系列】子程式返回值
【Multiprocessing系列】Pool
【Multiprocessing系列】Process
【Multiprocessing系列】Multiprocessing基礎