Queue
模塊實現了多生產者、多消費者隊列。當必須在多個線程之間安全地交換信息時,它在線程編程中特別有用,實現了所有必需的鎖定語義。
一、該模塊實現了三種類型的隊列,它們的區別僅在於檢索條目的順序:
1、FIFO 隊列,其添加的第一個任務是第一個檢索的任務。
2、LIFO 隊列,其最近添加的條目是第一個檢索的(像堆棧一樣運行)。
3、Priority 隊列,其條目將保持排序,並首先檢索最低值的條目。
二、該模塊定義了以下類和異常:
-
class
Queue.
Queue
(maxsize = 0 ) -
FIFO隊列的構造函數。 maxsize是一個整數,用於設置可以放入隊列的項目數的上限。達到此大小后,插入將阻止,直到消耗隊列項。如果 maxsize小於或等於零,則隊列大小為無限大。
-
class
Queue.
LifoQueue
(maxsize = 0 ) -
LIFO隊列的構造函數。 maxsize是一個整數,用於設置可以放入隊列的項目數的上限。達到此大小后,插入將阻止,直到消耗隊列項。如果 maxsize小於或等於零,則隊列大小為無限大。
-
class
Queue.
PriorityQueue
(maxsize = 0 ) -
Priority隊列的構造函數。 maxsize是一個整數,用於設置可以放入隊列的項目數的上限。達到此大小后,插入將阻止,直到消耗隊列項。如果 maxsize小於或等於零,則隊列大小為無限大。
-
exception
Queue.
Empty
-
在queue對象為空時調用非阻塞
get()
或get_nowait()
時引發異常。
-
exception
Queue.
Full
-
在queue對象已滿時調用非阻塞
put()
或put_nowait()
時引發異常。
三、queue對象提供下面描述的公共方法:
Queue.qsize()
返回隊列的大致大小(非准確值)。
Queue.empty()
如果隊列為空則返回True,否則返回False(僅限當前,不保證后續情況)。
Queue.full()
如果隊列已滿則返回True,否則返回False(僅限當前,不保證后續情況)。
Queue.put(item [,block [,timeout ] ] )
將item放入隊列。如果可選參數block為true 且 timeout為None,則在必要時阻止,直到有空閑槽可用。如果 timeout是一個正數,它會阻止最大超時時間,如果在該時間內沒有可用的空閑槽,則會引發Full異常。
反之(block為false),如果有空閑槽可以立即使用,則將item放入隊列,否則引發Full異常(在這種情況下忽略超時)。
Queue.put_nowait(item)
相當於 put(item, False)。
Queue.get([ block [,timeout ] ] )
從隊列中刪除並返回一個item。 如果可選的args塊為true且timeout為None(默認值),則在必要時阻止,直到某個項可用為止。 如果timeout是一個正數,它會阻止最多超時秒,如果在該時間內沒有可用的項,則會引發Empty異常。
反之(block為false),如果有item可以立即使用,則返回該tem,否則引發Empty異常(在這種情況下忽略超時)。
Queue.get_nowait()
-
相當於 get(False)。
四、queue對象還提供了兩種方法來支持跟蹤守護進程、消費者線程是否已完全處理入隊任務:
-
Queue.
task_done
() -
表示之前隊列的任務已完成。由隊列消費者線程使用。對於用於獲取任務的每個get(),對task_done()的后續調用會告知隊列該任務的處理已完成。
如果join() 當前正阻塞,則它將在所有條目都已處理后恢復(這意味着已為每個已放入隊列的條目收到task_done()調用)。
如果調用的次數超過隊列中放置的條目,則引發ValueError。
-
Queue.
join
() -
阻止直到隊列中的所有條目都已獲取並處理完畢。
每當條目添加到隊列時,未完成任務的計數就會增加。每當消費者線程調用
task_done()
以指示該條目已被檢索並且其上的所有工作都已完成時,計數就會下降。當未完成任務的數量降至零時,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 = True t.start() for item in source(): q.put(item) q.join() # block until all tasks are done