當需要創(chuàng)建的子進程數(shù)量不多時,可以直接利用multiprocessing中的Process動態(tài)成生多個進程娄猫,但如果是上百甚至上千個目標贱除,手動的去創(chuàng)建進程的工作量巨大,此時就可以用到multiprocessing模塊提供的Pool方法媳溺。
初始化Pool時月幌,可以指定一個最大進程數(shù),當有新的請求提交到Pool中時悬蔽,如果池還沒有滿扯躺,那么就會創(chuàng)建一個新的進程用來執(zhí)行該請求;但如果池中的進程數(shù)已經(jīng)達到指定的最大值蝎困,那么該請求就會等待录语,直到池中有進程結(jié)束,才會用之前的進程來執(zhí)行新的任務(wù)禾乘。
1澎埠、創(chuàng)建進程池
例:創(chuàng)建進程池
創(chuàng)建進程池時,需要導(dǎo)入multiprocessing模塊中的Pool類
如上圖所示始藕,我們利用Pool()類創(chuàng)建了一個容量為3的進程池蒲稳,并且利用apply_saync()方法向進程池中添加了10次任務(wù),該方法第一個參數(shù)接收一個函數(shù)名伍派,進程池中的進程會執(zhí)行這個函數(shù)中的程序江耀,第二個參數(shù)是一個元組類型,表示調(diào)用的函數(shù)的參數(shù)诉植。但是此時祥国,程序并不會運行,因為當前狀態(tài)下晾腔,向進程池添加了任務(wù)后舌稀,主程序就退出了,主程序不會等待所有進程結(jié)束就會自動結(jié)束建车。因此需要調(diào)用進程池的其他方法扩借。
調(diào)用close()方法,關(guān)閉進程池缤至,關(guān)閉后po不再接收新的請求潮罪。
調(diào)用join()方法,等待pool中所有子進程執(zhí)行完成领斥,必須放在close語句之后
當向進程池添加的任務(wù)多于進程池初始化的進程數(shù)時嫉到,不會導(dǎo)致堵塞,多余的任務(wù)會排隊等待月洛,直到有空閑進程去執(zhí)行這個任務(wù)
multiprocessing.Pool常用函數(shù)解析:
apply_async(func[, args[, kwds]]) :使用非阻塞方式調(diào)用func(并行執(zhí)行何恶,堵塞方式必須等待上一個進程退出才能執(zhí)行下一個進程),args為傳遞給func的參數(shù)列表嚼黔,kwds為傳遞給func的關(guān)鍵字參數(shù)列表细层;
close():關(guān)閉Pool惜辑,使其不再接受新的任務(wù);
terminate():不管任務(wù)是否完成疫赎,立即終止盛撑;
join():主進程阻塞,等待子進程的退出捧搞, 必須在close或terminate之后使用抵卫;
2、進程間通信
雖然可以利用Process()胎撇、Pool()創(chuàng)建不同數(shù)量進程介粘,但是進程之間都是相互獨立的。要想做到進程之間互相通信晚树,就需要借助第三方姻采,我們利用Queue類作為進程之間通信的媒介。
例:Queue的基本使用
隊列(queue)特點是先進先出(First in First out)题涨。在隊列中涉及到這樣的幾個操作:入隊(把數(shù)據(jù)添加到隊尾)偎谁、出隊(從隊首取出一個數(shù)據(jù))、隊列初始化(創(chuàng)建一個隊列)纲堵、銷毀一個隊列(把整個隊列的數(shù)據(jù)從內(nèi)存中刪除)巡雨、判斷隊列是否為空、判斷隊列是否滿席函、獲取隊列的長度铐望。
隊列對象的方法:
Queue.qsize() :返回queue的近似值。注意:qsize>0 不保證(get)取元素不阻塞茂附。qsize< maxsize不保證(put)存元素不會阻塞
Queue.empty():判斷隊列是否為空正蛙。和上面一樣注意
Queue.full():判斷是否滿了。和上面一樣注意
Queue.put(item,block=True,timeout=None): 往隊列里放數(shù)據(jù)营曼。如果滿了的話乒验,blocking = False 直接報 Full異常。如果blocking = True蒂阱,就是等一會锻全,timeout必須為 0 或正數(shù)。None為一直等下去录煤,0為不等鳄厌,正數(shù)n為等待n秒還不能存入,報Full異常妈踊。
?Queue.put_nowait(item):往隊列里存放元素了嚎,不等待
Queue.get(item,block=True,timeout=None): 從隊列里取數(shù)據(jù)。如果為空的話,blocking = False 直接報 empty異常歪泳。如果blocking = True萝勤,就是等一會,timeout必須為 0 或正數(shù)夹囚。None為一直等下去纵刘,0為不等,正數(shù)n為等待n秒還不能讀取荸哟,報empty異常。
?Queue.get_nowait(item):從隊列里取元素瞬捕,不等待
例:利用Queue實現(xiàn)進程間通信
如果要使用Pool創(chuàng)建進程鞍历,就需要使用multiprocessing.Manager()中的Queue(),而不是multiprocessing.Queue()肪虎,否則會得到一條如下的錯誤信息:
RuntimeError: Queue objects should only be shared between processes through inheritance.
例:進程池使用Queue進行通信