queue模塊實現了多生產者。多消費者隊列。在多線程環境下,該隊列能實現多個線程間安全的信息交換。
queue模塊介紹
在FIFO隊列中。依照先進先出的順序檢索條目。在LIFO隊列中,最后加入的條目最先檢索到(操作類似一個棧)。在優先級隊列中,條目被保存為有序的(使用heapq模塊)而且最小值的條目被最先檢索。
queue模塊定義了以下的類和異常:
class queue.Queue(maxsize=0)
class queue.LifoQueue(maxsize=0)
maxsize是一個整數,表示隊列的最大條目數。一旦隊列滿,插入將被堵塞直到隊列中存在空暇空間。假設maxsize小于等于0,隊列大小為無限。
class queue.PriorityQueue(maxsize=0)
假設maxsize小于等于0,隊列大小為無限。
最小值的條目被最先檢索到(最小值的條目即為被sorted(list(entries))[0]返回的條目)。
通常一個條目被保存為以下的形式:(priority_number, data)。
exception queue.Empty
exception queue.Full
Queue對象
Queue.qsize()
返回隊列的近似大小。注意,qsize() > 0并不能保證接下來的get()方法不被堵塞。相同。qsize() < maxsize也不能保證put()將不被堵塞。
Queue.empty()
假設隊列是空的。則返回True,否則False。假設empty()返回True,并不能保證接下來的put()調用將不被堵塞。類似的。empty()返回False也不能保證接下來的get()調用將不被堵塞。
Queue.full()
假設隊列滿則返回True,否則返回False。假設full()返回True,并不能保證接下來的get()調用將不被堵塞。
類似的,full()返回False也不能保證接下來的put()調用將不被堵塞。
Queue.put(item, block=True, timeout=None)
放item到隊列中。假設block是True,且timeout是None。該方法將一直等待直到有隊列有空余空間。假設timeout是一個正整數,該方法則最多堵塞timeout秒并拋出Full異常。假設block是False而且隊列滿,則直接拋出Full異常(這時timeout將被忽略)。
Queue.put_nowait(item)
等價于put(item, False)。
Queue.get(block=True, timeout=None)
從隊列中移除被返回一個條目。假設block是True而且timeout是None,該方法將堵塞直到隊列中有條目可用。假設timeout是正整數,該方法將最多堵塞timeout秒并拋出Empty異常。假設block是False而且隊列為空。則直接拋出Empty異常(這時timeout將被忽略)。
Queue.get_nowait()
等價于get(False)。
假設須要跟蹤進入隊列中的任務是否已經被精靈消費者線程處理完畢,能夠使用以下提供的兩個方法:
Queue.task_done()
表示一個先前的隊列中的任務完畢了。被隊列消費者線程使用。對于每一個get()獲取到的任務,接下來的task_done()的調用告訴隊列該任務的處理已經完畢。
假設join()調用正在堵塞,當隊列中全部的條目被處理后它將恢復運行(意味著task_done()調用將被放入隊列中的每一個條目接收到)。
假設調用次數超過了隊列中放置的條目數目,將拋出ValueError異常。
Queue.join()
堵塞直到隊列中全部條目都被獲取并處理。
當一個條目被添加到隊列時,未完畢任務的計數將添加。當一個消費者線程調用task_done()時,未完畢任務的計數將降低。
當未完畢任務的計數降低到0時,join()解鎖。
以下是一個詳細的樣例。用于說明怎么等待隊列任務完畢:
def worker():while True:item = q.get()do_work(item)q.task_done()q = Queue()
for i in range(num_worker_threads):t = Thread(target=worker)t.daemon = Truet.start()for item in source():q.put(item)q.join() # 堵塞直到全部任務完畢