"queue" --- 同期キュークラス
****************************

**ソースコード:** Lib/queue.py

======================================================================

"queue" モジュールは、複数プロデューサ-複数コンシューマ(multi-
producer, multi-consumer)キューを実装します。これは、複数のスレッドの
間で情報を安全に交換しなければならないときのマルチスレッドプログラミン
グで特に有益です。このモジュールの "Queue" クラスは、必要なすべてのロ
ックセマンティクスを実装しています。

このモジュールでは3種類のキューが実装されています。それらはキューから
取り出されるエントリの順番だけが違います。 FIFO (first-in, first-out,
先入れ先出し) キューでは、最初に追加されたエントリが最初に取り出されま
す。  LIFO (last-in, first-out, 後入れ先出し) キューでは、最後に追加さ
れたエントリが最初に取り出されます(スタックのように振る舞います)。 優
先順位付きキュー(priority queue)では、エントリは("heapq" モジュールを
利用して)ソートされ、 最も低い値のエントリが最初に取り出されます。

内部的には、これらの3種類のキューは競争スレッドを一時的にブロックする
ためにロックを使っています; しかし、スレッド内での再入を扱うようには設
計されていません。

In addition, the module implements a "simple" FIFO (first-in, first-
out) queue type, "SimpleQueue", whose specific implementation provides
additional guarantees in exchange for the smaller functionality.

"queue" モジュールは以下のクラスと例外を定義します:

class queue.Queue(maxsize=0)

   FIFO (first-in, first-out, 先入れ先出し) キューのコンストラクタです
   。 *maxsize* はキューに入れられる要素数の上限を設定する整数です。
   いったんこの大きさに達したら、挿入処理はキューの要素が消費されるま
   でブロックされます。 *maxsize* が0以下の場合は、キューの大きさは無
   限です。

class queue.LifoQueue(maxsize=0)

   LIFO (last-in, first-out, 後入れ先出し) キューのコンストラクタです
   。 *maxsize* はキューに入れられる要素数の上限を設定する整数です。
   いったんこの大きさに達したら、挿入処理はキューの要素が消費されるま
   でブロックされます。 *maxsize* が0以下の場合は、キューの大きさは無
   限です。

class queue.PriorityQueue(maxsize=0)

   優先順位付きキューのコンストラクタです。*maxsize* はキューに置くこ
   とのできる要素数の上限を設定する整数です。いったんこの大きさに達し
   たら、挿入はキューの要素が消費されるまでブロックされます。もし
   *maxsize* が0以下であるならば、キューの大きさは無限です。

   最小の値を持つ要素が最初に検索されます (最小の値を持つ値は、
   "min(entries)" によって返されるものです)。典型的な要素のパターンは
   、"(priority_number, data)" 形式のタプルです。

   If the *data* elements are not comparable, the data can be wrapped
   in a class that ignores the data item and only compares the
   priority number:

      from dataclasses import dataclass, field
      from typing import Any

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

class queue.SimpleQueue

   Constructor for an unbounded FIFO (first-in, first-out) queue.
   Simple queues lack advanced functionality such as task tracking.

   Added in version 3.7.

exception queue.Empty

   空の "Queue" オブジェクトで、非ブロックメソッド "get()" (または
   "get_nowait()") が呼ばれたとき、送出される例外です。

exception queue.Full

   満杯の "Queue" オブジェクトで、非ブロックメソッド "put()" (または
   "put_nowait()") が呼ばれたとき、送出される例外です。


キューオブジェクト
==================

キューオブジェクト("Queue", "LifoQueue", "PriorityQueue")は、以下の
publicメソッドを提供しています。

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* が真で
   *timeout* が "None" (デフォルト) の場合は、必要であればフリースロッ
   トが利用可能になるまでブロックします。 *timeout* が正の数の場合は、
   最大で *timeout* 秒間ブロックし、その時間内に空きスロットが利用可能
   にならなければ、例外 "Full" を送出します。 そうでない場合 (*block*
   が偽) は、空きスロットが直ちに利用できるならば、キューにアイテムを
   置きます。 できないならば、例外 "Full" を送出します (この場合
   *timeout* は無視されます)。

Queue.put_nowait(item)

   "put(item, block=False)" と等価です。

Queue.get(block=True, timeout=None)

   キューからアイテムを取り除き、それを返します。 オプション引数
   *block* が真で *timeout* が "None" (デフォルト) の場合は、必要であ
   ればアイテムが取り出せるようになるまでブロックします。 もし
   *timeout* が正の数の場合は、最大で *timeout* 秒間ブロックし、その時
   間内でアイテムが取り出せるようにならなければ、例外 "Empty" を送出し
   ます。 そうでない場合 (*block* が偽) は、直ちにアイテムが取り出せる
   ならば、それを返します。 できないならば、例外 "Empty" を送出します
   (この場合 *timeout* は無視されます)。

   Prior to 3.0 on POSIX systems, and for all versions on Windows, if
   *block* is true and *timeout* is "None", this operation goes into
   an uninterruptible wait on an underlying lock.  This means that no
   exceptions can occur, and in particular a SIGINT will not trigger a
   "KeyboardInterrupt".

Queue.get_nowait()

   "get(False)" と等価です。

キューに入れられたタスクが全てコンシューマスレッドに処理されたかどうか
を追跡するために 2つのメソッドが提供されます。

Queue.task_done()

   過去にキューに入れられたタスクが完了した事を示します。キューのコン
   シューマスレッドに利用されます。タスクの取り出しに使われた各
   "get()" の後に "task_done()" を呼び出すと、取り出したタスクに対する
   処理が完了した事をキューに教えます。

   "join()" がブロックされていた場合、全itemが処理された (キューに
   "put()" された全てのitemに対して "task_done()" が呼び出されたことを
   意味します) 時に復帰します。

   キューにある要素より多く呼び出された場合 "ValueError" が発生します
   。

Queue.join()

   キューにあるすべてのアイテムが取り出されて処理されるまでブロックし
   ます。

   未完了のタスクのカウント値はキューにアイテムが追加されるときは常に
   加算され、コンシューマースレッドが "task_done()" を呼び出してアイテ
   ムの回収とその全処理の完了が示されるときは常に減算されます。未完了
   のタスクのカウント値がゼロになった場合、"join()" のブロックが解除さ
   れます。

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

   import threading
   import 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)

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


SimpleQueue オブジェクト
========================

"SimpleQueue" オブジェクトは以下のpublicメソッドを提供しています。

SimpleQueue.qsize()

   キューの近似サイズを返します。ここで、qsize() > 0 であるからといっ
   て、後続の get() の呼び出しがブロックしないことが保証されないことに
   注意してください。

SimpleQueue.empty()

   キューが空の場合は "True" を返し、そうでなければ "False" を返します
   。 empty() が "False" を返しても、後続の get() の呼び出しがブロック
   しないことは保証されません。

SimpleQueue.put(item, block=True, timeout=None)

   Put *item* into the queue.  The method never blocks and always
   succeeds (except for potential low-level errors such as failure to
   allocate memory). The optional args *block* and *timeout* are
   ignored and only provided for compatibility with "Queue.put()".

   **CPython 実装の詳細:** 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, block=False)" と等価です。"Queue.put_nowait()" との互換
   性のためのメソッドです。

SimpleQueue.get(block=True, timeout=None)

   キューからアイテムを取り除き、それを返します。 オプション引数
   *block* が真で *timeout* が "None" (デフォルト) の場合は、必要であ
   ればアイテムが取り出せるようになるまでブロックします。 もし
   *timeout* が正の数の場合は、最大で *timeout* 秒間ブロックし、その時
   間内でアイテムが取り出せるようにならなければ、例外 "Empty" を送出し
   ます。 そうでない場合 (*block* が偽) は、直ちにアイテムが取り出せる
   ならば、それを返します。 できないならば、例外 "Empty" を送出します
   (この場合 *timeout* は無視されます)。

SimpleQueue.get_nowait()

   "get(False)" と等価です。

参考:

  "multiprocessing.Queue" クラス
     (マルチスレッドではなく) マルチプロセスの文脈で使用されるキューク
     ラス。

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