queue —同期されたキュークラス—Pythonドキュメント

提供:Dev Guides
< PythonPython/docs/3.8/library/queue
移動先:案内検索

queue —同期されたキュークラス

ソースコード: :source: `Lib / queue.py`



queue モジュールは、マルチプロデューサー、マルチコンシューマーキューを実装します。 これは、情報を複数のスレッド間で安全に交換する必要があるスレッドプログラミングで特に役立ちます。 このモジュールの Queue クラスは、必要なすべてのロックセマンティクスを実装します。

このモジュールは、エントリが取得される順序のみが異なる3種類のキューを実装します。 FIFO キューでは、最初に追加されたタスクが最初に取得されます。 LIFO キューでは、最後に追加されたエントリが最初に取得されます(スタックのように動作します)。 優先キューを使用すると、エントリは並べ替えられたままになり( heapq モジュールを使用)、最も値の小さいエントリが最初に取得されます。

内部的には、これら3種類のキューは、ロックを使用して競合するスレッドを一時的にブロックします。 ただし、スレッド内の再入可能性を処理するようには設計されていません。

さらに、このモジュールは「単純な」 FIFO キュータイプ SimpleQueue を実装します。この特定の実装は、より小さな機能と引き換えに追加の保証を提供します。

queue モジュールは、次のクラスと例外を定義します。

class queue.Queue(maxsize=0)
FIFO キューのコンストラクタ。 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 キューのコンストラクタ。 単純なキューには、タスク追跡などの高度な機能がありません。

バージョン3.7の新機能。

exception queue.Empty
空の Queue オブジェクトで非ブロッキング get()(または get_nowait())が呼び出されたときに例外が発生しました。
exception queue.Full
いっぱいになっている Queue オブジェクトで、非ブロッキング put()(または put_nowait())が呼び出されたときに例外が発生しました。

キューオブジェクト

キューオブジェクト( QueueLifoQueue 、または PriorityQueue )は、以下に説明するパブリックメソッドを提供します。

Queue.qsize()
キューのおおよそのサイズを返します。 qsize()> 0は、後続のget()がブロックされないことを保証するものではなく、qsize()
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で、 timeoutNone(デフォルト)の場合、空きスロットが使用可能になるまで必要に応じてブロックします。 timeout が正の数の場合、最大で timeout 秒をブロックし、その時間内に使用可能な空きスロットがない場合は Full 例外を発生させます。 それ以外の場合( block はfalse)、空きスロットがすぐに利用できる場合はアイテムをキューに入れます。それ以外の場合は、 Full 例外を発生させます( timeout は無視されます)。場合)。
Queue.put_nowait(item)
put(item, False)と同等です。
Queue.get(block=True, timeout=None)

キューからアイテムを削除して返します。 オプションの引数 block がtrueで、 timeoutNone(デフォルト)の場合、アイテムが使用可能になるまで必要に応じてブロックします。 timeout が正の数の場合、最大で timeout 秒をブロックし、その時間内に使用可能なアイテムがない場合は Empty 例外を発生させます。 それ以外の場合( block がfalse)、すぐに使用できる場合はアイテムを返します。それ以外の場合は、 Empty 例外を発生させます(その場合、 timeout は無視されます)。

POSIXシステムの3.0より前、およびWindowsのすべてのバージョンで、 block がtrueで、 timeoutNoneの場合、この操作は、基になるシステムで中断できない待機状態になります。ロック。 これは、例外が発生しないことを意味し、特にSIGINTは KeyboardInterrupt をトリガーしません。

Queue.get_nowait()
get(False)と同等です。

エンキューされたタスクがデーモンコンシューマスレッドによって完全に処理されたかどうかの追跡をサポートするために、2つの方法が提供されています。

Queue.task_done()

以前にキューに入れられたタスクが完了したことを示します。 キューコンシューマスレッドによって使用されます。 タスクのフェッチに使用される get()ごとに、 task_done()への後続の呼び出しは、タスクの処理が完了したことをキューに通知します。

join()が現在ブロックしている場合、すべてのアイテムが処理されると再開されます(つまり、 putされたすべてのアイテムに対して task_done()呼び出しが受信されました()をキューに入れます)。

キューに配置されたアイテムよりも多く呼び出された場合、 ValueError を発生させます。

Queue.join()

キュー内のすべてのアイテムが取得および処理されるまでブロックします。

アイテムがキューに追加されるたびに、未完了のタスクの数が増えます。 コンシューマースレッドが task_done()を呼び出して、アイテムが取得され、そのアイテムに対するすべての作業が完了したことを示すたびに、カウントが減少します。 未完了のタスクの数がゼロになると、 join()のブロックが解除されます。

キューに入れられたタスクが完了するのを待つ方法の例:

import threading, queue

q = queue.Queue()

def worker():
    while True:
        item = q.get()
        print(f'Working on {item}')
        print(f'Finished {item}')
        q.task_done()

# turn-on the worker thread
threading.Thread(target=worker, daemon=True).start()

# send thirty task requests to the worker
for item in range(30):
    q.put(item)
print('All task requests sent\n', end='')

# block until all tasks are done
q.join()
print('All work completed')

SimpleQueueオブジェクト

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()との互換性のためにのみ提供されます。
SimpleQueue.put_nowait(item)
put(item)と同等で、 Queue.put_nowait()との互換性のために提供されています。
SimpleQueue.get(block=True, timeout=None)
キューからアイテムを削除して返します。 オプションの引数 block がtrueで、 timeoutNone(デフォルト)の場合、アイテムが使用可能になるまで必要に応じてブロックします。 timeout が正の数の場合、最大で timeout 秒をブロックし、その時間内に使用可能なアイテムがない場合は Empty 例外を発生させます。 それ以外の場合( block がfalse)、すぐに使用できる場合はアイテムを返します。それ以外の場合は、 Empty 例外を発生させます(その場合、 timeout は無視されます)。
SimpleQueue.get_nowait()
get(False)と同等です。

も参照してください

クラス multiprocessing.Queue
(マルチスレッドではなく)マルチプロセッシングコンテキストで使用するためのキュークラス。

collections.deque は、ロックを必要とせず、インデックス作成もサポートする高速アトミック append()および popleft()操作を備えた無制限キューの代替実装です。