python 程序池pool使用詳解
和選用執行緒池來關係多執行緒類似,當程式中設定到多程序程式設計時,Python 提供了更好的管理多個程序的方式,就是使用程序池。
在利用 Python 進行系統管理的時候,特別是同時操作多個檔案目錄,或者遠端控制多臺主機,並行操作可以節約大量的時間。
當被操作物件數目不大時,可以直接利用 multiprocessing 中的 Process 動態生成多個程序,十幾個還好,但如果是上百個,上千個目標,手動的去限制程序數量卻又太過繁瑣,此時可以發揮程序池的功效。
Pool可以提供指定數量的程序供使用者呼叫,當有新的請求提交到 pool 中時,如果程序池還沒有滿,那麼就會建立一個新的程序用來執行該請求;但如果池中的程序數已經達到規定最大值,那麼該請求就會等待,直到池中有程序結束,才會建立新的程序來它。
Python multiprocessing 模組提供了 Pool() 函式,專門用來建立一個程序池,該函式的語法格式如下:
multiprocessing.Pool( processes )
其中,processes 引數用於指定該程序池中包含的程序數。
如果程序是 None,則預設使用 os.cpu_count() 返回的數字(根據本地的 cpu 個數決定,processes 小於等於本地的 cpu 個數)。
請看下面的例項:
from multiprocessing import Pool import os import time import random def worker(msg): t_start = time.time() print("%s開始執行,程序號為%d" % (msg,os.getpid())) # random.random()隨機生成0~1之間的浮點數 time.sleep(random.random()*2) t_stop = time.time() print(msg,"執行完畢,耗時%0.2f" % (t_stop-t_start)) if __name__ == "__main__": po = Pool(3) # 定義一個程序池,最大程序數3 for i in range(0,8): # Pool().apply_async(要呼叫的目標,(傳遞給目標的引數元祖,)) # 每次迴圈將會用空閒出來的子程序去呼叫目標 po.apply_async(worker,(i,)) print("----start----") # 關閉程序池,關閉後po不再接收新的請求 po.close() # 等待po中所有子程序執行完成,必須放在close語句之後 po.join() print("-----end-----")
執行結果:
multiprocessing.Pool 常用方法說明
apply_async(func[,args[,kwds]]) :使用非阻塞方式呼叫 func(並行執行,堵塞方式必須等待上一個程序退出才能執行下一個程序),args 為傳遞給 func 的引數列表,kwds 為傳遞給 func 的關鍵字引數列表。
close():關閉 Pool,使其不再接受新的任務。
terminate():不管任務是否完成,立即終止。
join():主程序阻塞,等待子程序的退出, 必須在 close 或 terminate 之後使用。
程序池中的 Queue
如果要使用 Pool 建立程序,就需要使用 multiprocessing.Manager() 中的 Queue(),而不是 multiprocessing.Queue(),否則會得到一條如下的錯誤資訊:
RuntimeError: Queue objects should only be shared between processes through inheritance.
下面的例項演示了程序池中的程序如何通訊:
from multiprocessing import Manager,Pool import os import time import random def writer(q): print("writer啟動(%s),父程序為(%s)" % (os.getpid(),os.getppid())) for i in "xiaoming": q.put(i) def reader(q): print("reader啟動(%s),os.getppid())) for i in range(q.qsize()): print("reader從Queue獲取到訊息:%s" % q.get(True)) if __name__ == "__main__": print("(%s) start" % os.getpid()) # 使用Manager中的Queue q = Manager().Queue() po = Pool() po.apply_async(writer,(q,)) # 先讓上面的任務向Queue存入資料,然後再讓下面的任務開始從中取資料 time.sleep(1) po.apply_async(reader,)) po.close() po.join() print("(%s) End" % os.getpid())
執行結果:
(17528) start writer啟動(2216),父程序為(17528) reader啟動(2216),父程序為(17528) reader從Queue獲取到訊息:x reader從Queue獲取到訊息:i reader從Queue獲取到訊息:a reader從Queue獲取到訊息:o reader從Queue獲取到訊息:m reader從Queue獲取到訊息:i reader從Queue獲取到訊息:n reader從Queue獲取到訊息:g (17528) End
以上就是python 程序池pool使用詳解的詳細內容,更多關於python 程序池pool的資料請關注我們其它相關文章!