在多線程multiprocessing模塊中,有兩個類,Queue(隊列)和Process(進程);
在Queue.py中也有一個Queue類,這兩個Queue的區別?
from multiprocessing import Queue,Process引入multiprocessing模塊中的隊列和進程類
隊列Queue:
Queue是python中的標准庫,可以直接import引用在隊列中;Queue.Queue(maxsize)創建隊列對象,如果不提供maxsize,則隊列數無限制。
# _*_ encoding:utf-8 _*_ import Queue q = Queue.Queue(10) q.put('SB') q.put('You') print (q.get()) print (q.get())
當一個隊列為空的時候,用get取回堵塞,所以一般取隊列的時候會用,get_nowait()方法,這個方法在向一個空隊列取值的時候會拋一個Empty異常,所以一般會先判斷隊列是否為空,如果不為空則取值;
不阻塞的方式取隊列
判斷隊列是否為空,為空返回True,不為空返回False
返回隊列的長度
Queue.get([block[, timeout]]) 獲取隊列,timeout等待時間
Queue.get_nowait() 相當Queue.get(False)
非阻塞 Queue.put(item) 寫入隊列,timeout等待時間
Queue.put_nowait(item) 相當Queue.put(item, False)
Multiprocessing中使用子進程的概念Process:
from multiprocessing import Process
可以通過Process來構造一個子進程
p=Process(target=fun,args=(args))
再通過p.start()來啟動子進程
再通過p.join()方法來使得子進程運行結束后再執行父進程
在multiprocessing中使用pool:
如果需要多個子進程時可以考慮使用進程池(pool)來管理
Pool創建子進程的方法與Process不同,是通過p.apply_async(func,args=(args))實現,一個池子里能同時運行的任務是取決你電腦CPU的數量,如果是4個CPU,那么會有task0,task1,task2,task3同時啟動,task4需要在某個進程結束后才開始。
多個子進程間的通信:
多個子進程間的通信就要采用第一步中的隊列Queue,比如,有以下需求,一個子進程向隊列中寫數據,另一個進程從隊列中取數據,
# _*_ encoding:utf-8 _*_ from multiprocessing import Process,Queue,Pool,Pipe import os,time,random #寫數據進程執行的代碼: def write(p): for value in ['A','B','C']: print ('Write---Before Put value---Put %s to queue...' % value) p.put(value) print ('Write---After Put value') time.sleep(random.random()) print ('Write---After sleep') #讀數據進程執行的代碼: def read(p): while True: print ('Read---Before get value') value = p.get(True) print ('Read---After get value---Get %s from queue.' % value) if __name__ == '__main__': #父進程創建Queue,並傳給各個子進程: p = Queue() pw = Process(target=write,args=(p,)) pr = Process(target=read,args=(p,)) #啟動子進程pw,寫入: pw.start() #啟動子進程pr,讀取: pr.start() #等待pw結束: pw.join() #pr進程里是死循環,無法等待其結束,只能強行終止: pr.terminate()
關於鎖的應用,在不同程序間如果有同時對同一個隊列操作的時候,為了避免錯誤,可以在某個函數操作隊列的時候給它加把鎖,這樣在同一個時間內則只能有一個子進程對隊列進行操作,鎖也要在manager對象中的鎖