進程池: python
在利用Python進行系統管理的時候,特別是同時操做多個文件目錄,或者遠程控制多臺主機,並行操做能夠節約大量的時間。當被操做對象數目不大時,能夠直接利用multiprocessing中的Process動態成生多個進程,十幾個還好,但若是是上百個,上千個目標,手動的去限制進程數量卻又太過繁瑣,此時能夠發揮進程池的功效。 併發
Pool能夠提供指定數量的進程供用戶調用,當有新的請求提交到pool中時,若是池尚未滿,那麼就會建立一個新的進程用來執行該請求;但若是池中的進程數已經達到規定最大值,那麼該請求就會等待,直到池中有進程結束,纔會建立新的進程來它。app
如何使用進程池?async
1 如何使用進程池執行函數?ide
a 不返回參數函數
# -*- coding: UTF-8 -*- from multiprocessing import Process,Manager,Lock,Pool #要在調用進程池執行的函數 def sayHi(num): print "def print result:",num #進程池最大運行數 p = Pool(processes=4) #模擬併發調用線程池 for i in range(10): p.apply_async(sayHi,[i]) 執行結果: # python demo.py def print result: 0 def print result: 1 def print result: 2 def print result: 3 def print result: 4 def print result: 5
apply_async(func[, args[, kwds[, callback]]]) 它是非阻塞,apply(func[, args[, kwds]])是阻塞的(理解區別,看例1例2結果區別)spa
2 進程池使用之坑~~線程
# -*- coding: UTF-8 -*- from multiprocessing import Process,Manager,Lock,Pool #要在調用進程池執行的函數 def sayHi(num): print "def print result:",num #進程池最大運行數 p = Pool(processes=4) #模擬併發調用線程池 for i in range(10): p.apply_async(sayHi,[i])
執行結果:orm
[root@python thread]# python pool.py def print result: 0 def print result: 1 def print result: 2 def print result: 3 def print result: 4 def print result: 5 [root@python thread]# python pool.py def print result: 0 def print result: 1 def print result: 2 def print result: 3 def print result: 4 def print result: 5 def print result: 6 [root@python thread]# python pool.py [root@python thread]# python pool.py [root@python thread]# python pool.py
從上面的例子能夠看出,咱們連續執行pool.py腳本,後面的腳本卻沒有輸出應有的結果,爲何?對象
首先對上列程序進行細微調整:
# -*- coding: UTF-8 -*- from multiprocessing import Process,Manager,Lock,Pool def sayHi(num): print "def print result:",num p = Pool(processes=4) for i in range(10): p.apply_async(sayHi,[i]) p.close() p.join() #調用join以前,先調用close函數,不然會出錯。執行完close後不會有新的進程加入到pool,join函數等待全部子進程結束
返回結果:
[root@python thread]# python pool.py def print result: 0 def print result: 1 def print result: 2 def print result: 3 def print result: 4 def print result: 5 def print result: 6 def print result: 9 def print result: 8 def print result: 7 [root@python thread]# python pool.py def print result: 0 def print result: 1 def print result: 2 def print result: 4 def print result: 3 def print result: 5 def print result: 6 def print result: 7 def print result: 8 def print result: 9 [root@python thread]# python pool.py def print result: 0 def print result: 1 def print result: 2 def print result: 3 def print result: 4 def print result: 5 def print result: 7 def print result: 8 def print result: 9
此次執行徹底沒有問題,那麼爲什麼加入close()和join()方法後就會執行正確呢?
close() 關閉pool,使其不在接受新的任務。
terminate() 結束工做進程,不在處理未完成的任務。
join() 主進程阻塞,等待子進程的退出, join方法要在close或terminate以後使用。
原來重點是join方法,若是不阻塞主進程,會致使主進程往下運行到結束,子進程都尚未返回結果
3 進程池調用後返回參數
# -*- coding: UTF-8 -*- from multiprocessing import Process,Manager,Lock,Pool def sayHi(num): return num*num p = Pool(processes=4) #申明一個列表,用來存放各進程返回的結果 result_list =[] for i in range(10): result_list.append(p.apply_async(sayHi,[i])) #將返回結果append到列表中 #循環讀出列表返回的結果 for res in result_list: print "the result:",res.get()
注:get()函數得出每一個返回結果的值
執行結果:
[root@python thread]# python pool.py the result: 0 the result: 1 the result: 4 the result: 9 the result: 16 the result: 25 the result: 36 the result: 49 the result: 64 the result: 81 [root@python thread]# python pool.py the result: 0 the result: 1 the result: 4 the result: 9 the result: 16 the result: 25 the result: 36 the result: 49 the result: 64 the result: 81 [root@python thread]# python pool.py the result: 0 the result: 1 the result: 4 the result: 9 the result: 16 the result: 25 the result: 36 the result: 49 the result: 64
將結果經過return返回後,寫入列表後,而後再循環讀出,你會發現及時不須要join方法,腳本仍然能正常顯示。
可是爲了代碼更加穩定,仍是建議增長主進程阻塞(除非主進程須要等待子進程返回結果):
# -*- coding: UTF-8 -*- from multiprocessing import Process,Manager,Lock,Pool def sayHi(num): return num*num p = Pool(processes=4) #申明一個列表,用來存放各進程返回的結果 result_list =[] for i in range(10): result_list.append(p.apply_async(sayHi,[i])) #將返回結果append到列表中 p.close() p.join() #調用join以前,先調用close函數,不然會出錯。執行完close後不會有新的進程加入到pool,join函數等待全部子進程結束 #循環讀出列表返回的結果 for res in result_list: print "the result:",res.get()