python 進程池pool簡單實例

進程池:

   在利用Python進行系統管理的時候,特別是同時操作多個文件目錄,或者遠程控制多台主機,並行操作可以節約大量的時間。當被操作對象數目不大時,可以直接利用multiprocessing中的Process動態成生多個進程,十幾個還好,但如果是上百個,上千個目標,手動的去限制進程數量卻又太過繁瑣,此時可以發揮進程池的功效。  

    Pool可以提供指定數量的進程供用戶調用,當有新的請求提交到pool中時,如果池還沒有滿,那麼就會創建一個新的進程用來執行該請求;但如果池中的進程數已經達到規定最大值,那麼該請求就會等待,直到池中有進程結束,才會創建新的進程來它。

如何使用進程池?

1 如何使用進程池執行函數?

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結果區別)

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])

執行結果:

[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()