python的multiprocessing模塊進程建立、資源回收-Process,Pool

python的multiprocessing有兩種建立進程的方式,每種建立方式和進程資源的回收都不太相同,下面分別針對Process,Pool及系統自帶的fork三種進程分析。html

1.方式一:fork()python

舉例:
linux

1 import os 2 pid = os.fork() # 建立一個子進程
3 os.wait() # 等待子進程結束釋放資源
4 pid爲0的表明子進程。

缺點:
1.兼容性差,只能在類linux系統下使用,windows系統不可以使用;
2.擴展性差,當須要多條進程的時候,進程管理變得很複雜;
3.會產生「孤兒」進程和「殭屍」進程,須要手動回收資源。
優勢:
是系統自帶的接近低層的建立方式,運行效率高。
windows

 

2.方式二:Process進程
舉例:app

1 import multiprocessing as ms 2 def test(): 3 pass
4 p1 = ms.Process(target=test) # 建立子進程
5 p1.start() # 子進程 開始執行
6 p1.join() # 等待子進程結束

特色:
1.注意:Process對象能夠建立進程,但Process對象不是進程,其刪除與否與系統資源是否被回收沒有直接的關係。
2.主進程執行完畢後會默認等待子進程結束後回收資源,不須要手動回收資源;join()函數用來控制子進程
    結束的順序,其內部也有一個清除殭屍進程的函數,能夠回收資源;
3.Process進程建立時,子進程會將主進程的Process對象徹底複製一份,這樣在主進程和子進程各有一個Process
   對象,可是p1.start()啓動的是子進程,主進程中的Process對象做爲一個靜態對象存在,不執行。
4.當子進程執行完畢後,會產生一個殭屍進程,其會被join函數回收,或者再有一條進程開啓,start函數也會回收
殭屍進程,因此不必定須要寫join函數。
5.windows系統在子進程結束後會當即自動清除子進程的Process對象,而linux系統子進程的Process對象
若是沒有join函數和start函數的話會在主進程結束後統一清除。async

另外還能夠經過繼承Process對象來重寫run方法建立進程,這裏再也不贅述。函數

 

3.進程池Pool:spa

 1 import mutiprocessing as ms  2 def test():  3 pass
 4 p1 = Pool(5) # 建立5條進程
 5 for i in range(10):  6 p1.apply_async(test) # 向進程池添加任務
 7 p1.close() # 關閉進程池,再也不接受請求
 8 po.join() # 等待全部的子進程結束
 9 while Ture: 10 pass

分析:
1.如上,進程池Pool被建立出來後,即便實際須要建立的進程數遠遠大於進程池的最大上限,p1.apply_async(test)代碼
   依舊會不停的執行,並不會停下等待;至關於向進程池提交了10個請求,會被放到一個隊列中;
2.可是有一點很重要,當執行完p1 = Pool(5)這條代碼後,5條進程已經被建立出來了,只是尚未爲他們各自
   分配任務,也就是說,不管有多少任務,實際的進程數只有5條,計算機每次最多5條進程並行。線程

3.當Pool中有進程任務執行完畢後,這條進程資源會被釋放,pool會按先進先出的原則取出一個新的請求給空閒的
   進程繼續執行;
4.當Pool全部的進程任務完成後,會產生5個殭屍進程,若是主線程不結束,系統不會自動回收資源,須要調用join函數去回收。
5.建立Pool池時,若是不指定進程最大數量,默認建立的進程數爲系統的內核數量.code

  另外還有一種阻塞式添加任務的方法,p1.apply(test),其每次只能向進程池添加一條任務,而後for循環會被堵塞等待,
直到添加的任務被執行完畢,進程池中的5個進程交替執行新來的任務,至關於單進程了。

進程在windows和linux系統下的對比

相關文章
相關標籤/搜索