python 進程池pool簡單實例

進程池:   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方法,若是不阻塞主進程,會致使主進程往下運行到結束,子進程都尚未返回結果

   

  進程池調用後返回參數

# -*- 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()
相關文章
相關標籤/搜索