queue --- 一個同步的隊列類

模塊實現了三種類型的隊列,它們的區別僅僅是條目取回的順序。在 FIFO 隊列中,先添加的任務先取回。在 LIFO 隊列中,最近被添加的條目先取回(操作類似一個堆棧)。優先級隊列中,條目將保持排序( 使用 heapq 模塊 ) 並且最小值的條目第一個返回。

在內部,這三個類型的隊列使用鎖來臨時阻塞競爭線程;然而,它們並未被設計用於線程的重入性處理。

此外,模塊實現了一個 “簡單的” FIFO 隊列類型, SimpleQueue ,這個特殊實現爲小功能在交換中提供額外的保障。

class queue.Queue(maxsize=0)
Constructor for a FIFO queue. maxsize is an integer that sets the upperbound limit on the number of items that can be placed in the queue. Insertion will block once this size has been reached, until queue items are consumed. If maxsize is less than or equal to zero, the queue size is infinite.

class queue.LifoQueue(maxsize=0)
LIFO 隊列構造函數。 maxsize 是個整數,用於設置可以放入隊列中的項目數的上限。當達到這個大小的時候,插入操作將阻塞至隊列中的項目被消費掉。如果 maxsize 小於等於零,隊列尺寸爲無限大。

class queue.LifoQueue(maxsize=0)
LIFO 隊列構造函數。 maxsize 是個整數,用於設置可以放入隊列中的項目數的上限。當達到這個大小的時候,插入操作將阻塞至隊列中的項目被消費掉。如果 maxsize 小於等於零,隊列尺寸爲無限大。

class queue.PriorityQueue(maxsize=0)
優先級隊列構造函數。 maxsize 是個整數,用於設置可以放入隊列中的項目數的上限。當達到這個大小的時候,插入操作將阻塞至隊列中的項目被消費掉。如果 maxsize 小於等於零,隊列尺寸爲無限大。

最小值先被取出( 最小值條目是由 sorted(list(entries))[0] 返回的條目)。條目的典型模式是一個以下形式的元組: (priority_number, data) 。

如果 data 元素沒有可比性,數據將被包裝在一個類中,忽略數據值,僅僅比較優先級數字 :

from dataclasses import dataclass, field
from typing import Any

@dataclass(order=True)
class PrioritizedItem:
    priority: int
    item: Any=field(compare=False)

class queue.SimpleQueue
無界的 FIFO 隊列構造函數。簡單的隊列,缺少任務跟蹤等高級功能。

exception queue.Empty
對空的 Queue 對象,調用非阻塞的 get() (or get_nowait()) 時,引發的異常。

exception queue.Full
對滿的 Queue 對象,調用非阻塞的 put() (or put_nowait()) 時,引發的異常。

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),如果空閒插槽立即可用,則把 item 放入隊列,否則引發 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 將被忽略)。

POSIX系統3.0之前,以及所有版本的Windows系統中,如果 block 是 true 並且 timeout 是 None , 這個操作將進入基礎鎖的不間斷等待。這意味着,沒有異常能發生,尤其是 SIGINT 將不會觸發 KeyboardInterrupt 異常。

Queue.get_nowait()
相當於 get(False) 。

提供了兩個方法,用於支持跟蹤 排隊的任務 是否 被守護的消費者線程 完整的處理。

Queue.task_done()
表示前面排隊的任務已經被完成。被隊列的消費者線程使用。每個 get() 被用於獲取一個任務, 後續調用 task_done() 告訴隊列,該任務的處理已經完成。

如果 join() 當前正在阻塞,在所有條目都被處理後,將解除阻塞(意味着每個 put() 進隊列的條目的 task_done() 都被收到)。

如果被調用的次數多於放入隊列中的項目數量,將引發 ValueError 異常 。

Queue.join()
阻塞至隊列中所有的元素都被接收和處理完畢。

當條目添加到隊列的時候,未完成任務的計數就會增加。每當消費者線程調用 task_done() 表示這個條目已經被回收,該條目所有工作已經完成,未完成計數就會減少。當未完成計數降到零的時候, join() 阻塞被解除。

如何等待排隊的任務被完成的示例:

def worker():
    while True:
        item = q.get()
        if item is None:
            break
        do_work(item)
        q.task_done()

q = queue.Queue()
threads = []
for i in range(num_worker_threads):
    t = threading.Thread(target=worker)
    t.start()
    threads.append(t)

for item in source():
    q.put(item)

# block until all tasks are done
q.join()

# stop workers
for i in range(num_worker_threads):
    q.put(None)
for t in threads:
    t.join()

SimpleQueue 對象

SimpleQueue.qsize()
返回隊列的大致大小。注意,qsize() > 0 不保證後續的 get() 不被阻塞。

SimpleQueue.empty()
如果隊列爲空,返回 True ,否則返回 False 。如果 empty() 返回 False ,不保證後續調用的 get() 不被阻塞。

SimpleQueue.put(item, block=True, timeout=None)
將 item 放入隊列。此方法永不阻塞,始終成功(除了潛在的低級錯誤,例如內存分配失敗)。可選參數 block 和 timeout 僅僅是爲了保持 Queue.put() 的兼容性而提供,其值被忽略。

CPython implementation detail: This method has a C implementation which is reentrant. That is, a put() or get() call can be interrupted by another put() call in the same thread without deadlocking or corrupting internal state inside the queue. This makes it appropriate for use in destructors such as del methods or weakref callbacks.

SimpleQueue.put_nowait(item)
相當於 put(item) ,僅爲保持 Queue.put_nowait() 兼容性而提供。

SimpleQueue.get(block=True, timeout=None)
從隊列中移除並返回一個項目。如果可選參數 block 是 true 並且 timeout 是 None (默認值),則在必要時阻塞至項目可得到。如果 timeout 是個正數,將最多阻塞 timeout 秒,如果在這段時間內項目不能得到,將引發 Empty 異常。反之 (block 是 false) , 如果一個項目立即可得到,則返回一個項目,否則引發 Empty 異常 (這種情況下,timeout 將被忽略)。

SimpleQueue.get_nowait()
相當於 get(False) 。

參見
class multiprocessing.Queue
一個用於多進程上下文的隊列類(而不是多線程)。

collections.deque is an alternative implementation of unbounded queues with fast atomic append() and popleft() operations that do not require locking.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章