"threading" --- スレッドベースの並列処理
****************************************

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

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

このモジュールでは、高水準のスレッドインターフェースをより低水準 な
"_thread" モジュールの上に構築しています。

バージョン 3.7 で変更: このモジュールは以前はオプションでしたが、常に
利用可能なモジュールとなりました。

参考:

  "concurrent.futures.ThreadPoolExecutor" offers a higher level
  interface to push tasks to a background thread without blocking
  execution of the calling thread, while still being able to retrieve
  their results when needed.

  "queue" provides a thread-safe interface for exchanging data between
  running threads.

  "asyncio" offers an alternative approach to achieving task level
  concurrency without requiring the use of multiple operating system
  threads.

注釈:

  In the Python 2.x series, this module contained "camelCase" names
  for some methods and functions. These are deprecated as of Python
  3.10, but they are still supported for compatibility with Python 2.5
  and lower.

**CPython 実装の詳細:** CPython は *Global Interpreter Lock* のため、
ある時点で Python コードを実行できるスレッドは1つに限られます (ただし
、いくつかのパフォーマンスが強く求められるライブラリはこの制限を克服し
ています)。アプリケーションにマルチコアマシンの計算能力をより良く利用
させたい場合は、 "multiprocessing" モジュールや
"concurrent.futures.ProcessPoolExecutor" の利用をお勧めします。 ただし
、I/Oバウンドなタスクを並行して複数走らせたい場合においては、 マルチス
レッドは正しい選択肢です。

このモジュールは以下の関数を定義しています:

threading.active_count()

   生存中の "Thread" オブジェクトの数を返します。この数は
   "enumerate()" の返すリストの長さと同じです。

   関数``activeCount``はこの関数の非推奨エイリアスです。

threading.current_thread()

   関数を呼び出している処理のスレッドに対応する "Thread" オブジェクト
   を返します。関数を呼び出している処理のスレッドが "threading" モジュ
   ールで生成したものでない場合、限定的な機能しかもたないダミースレッ
   ドオブジェクトを返します。

   関数``currentThread``はこの関数の非推奨エイリアスです。

threading.excepthook(args, /)

   "Thread.run()" で発生したキャッチされない例外を処理する。

   (実) 引数*args*は以下の属性をもちます:

   * *exc_type*: 例外の型

   * *exc_value*: 例外の値、"None" の可能性がある。

   * *exc_traceback*: Exception traceback, can be "None".

   * *thread*: Thread which raised the exception, can be "None".

   If *exc_type* is "SystemExit", the exception is silently ignored.
   Otherwise, the exception is printed out on "sys.stderr".

   If  this function raises an exception, "sys.excepthook()" is called
   to handle it.

   "threading.excepthook()" can be overridden to control how uncaught
   exceptions raised by "Thread.run()" are handled.

   Storing *exc_value* using a custom hook can create a reference
   cycle. It should be cleared explicitly to break the reference cycle
   when the exception is no longer needed.

   Storing *thread* using a custom hook can resurrect it if it is set
   to an object which is being finalized. Avoid storing *thread* after
   the custom hook completes to avoid resurrecting objects.

   参考: "sys.excepthook()" handles uncaught exceptions.

   バージョン 3.8 で追加.

threading.__excepthook__

   Holds the original value of "threading.excepthook()". It is saved
   so that the original value can be restored in case they happen to
   get replaced with broken or alternative objects.

   バージョン 3.10 で追加.

threading.get_ident()

   現在のスレッドの 'スレッドID' を返します。非ゼロの整数です。この値
   は直接の意味を持っていません; 例えばスレッド特有のデータの辞書に索
   引をつけるためのような、マジッククッキーとして意図されています。ス
   レッドが終了し、他のスレッドが作られたとき、スレッド ID は再利用さ
   れるかもしれません。

   バージョン 3.3 で追加.

threading.get_native_id()

   Return the native integral Thread ID of the current thread assigned
   by the kernel. This is a non-negative integer. Its value may be
   used to uniquely identify this particular thread system-wide (until
   the thread terminates, after which the value may be recycled by the
   OS).

   利用可能な環境: Windows, FreeBSD, Linux, macOS, OpenBSD, NetBSD,
   AIX。

   バージョン 3.8 で追加.

threading.enumerate()

   現在、アクティブな "Thread" オブジェクト全てのリストを返します。リ
   ストには、デーモンスレッド (daemonic thread)、 "current_thread()"
   の生成するダミースレッドオブジェクトが入ります。終了したスレッドと
   まだ開始していないスレッドは入りません。しかし、主スレッドは、たと
   え終了しても、常に結果に含まれます。

threading.main_thread()

   main "Thread" オブジェクトを返します。通常の条件では、メインスレッ
   ドはPythonインタプリタが起動したスレッドを指します。

   バージョン 3.4 で追加.

threading.settrace(func)

   "threading" モジュールを使って開始した全てのスレッドにトレース関数
   を設定します。 *func* は各スレッドの "run()" を呼び出す前にスレッド
   の "sys.settrace()" に渡されます。

threading.gettrace()

   "settrace()" 関数で設定したトレース関数を取得します。

   バージョン 3.10 で追加.

threading.setprofile(func)

   "threading" モジュールを使って開始した全てのスレッドにプロファイル
   関数を設定します。 *func* は各スレッドの "run()" を呼び出す前にスレ
   ッドの "sys.setprofile()" に渡されます。

threading.getprofile()

   "setprofile()" 関数で設定したプロファイラ関数を取得します。

   バージョン 3.10 で追加.

threading.stack_size([size])

   新しいスレッドを作るときのスレッドスタックサイズを返します。オプシ
   ョンの *size* 引数にはこれ以降に作成するスレッドのスタックサイズを
   指定し、0 (プラットフォームのデフォルト値または設定されたデフォルト
   値) か、 32,768 (32 KiB) 以上の正の整数でなければなりません。*size*
   が指定されない場合 0 が使われます。スレッドのスタックサイズの変更が
   サポートされていない場合、 "RuntimeError" を送出します。不正なスタ
   ックサイズが指定された場合、 "ValueError" を送出して、スタックサイ
   ズは変更されません。32 KiB は現在のインタープリタ自身のために十分で
   あると保証された最小のスタックサイズです。いくつかのプラットフォー
   ムではスタックサイズに対して制限があることに注意してください。例え
   ば最小のスタックサイズが 32 KiB より大きかったり、システムのメモリ
   ページサイズ の整数倍の必要があるなどです。この制限についてはプラッ
   トフォームのドキュメントを参照してください (一般的なページサイズは
   4 KiB なので、プラットフォームに関する情報がない場合は 4096 の整数
   倍のスタックサイズを選ぶといいかもしれません)。

   Availability: Windows, systems with POSIX threads.

このモジュールでは以下の定数も定義しています:

threading.TIMEOUT_MAX

   ブロックする関数 ("Lock.acquire()", "RLock.acquire()",
   "Condition.wait()" など) の *timeout* 引数に許される最大値。これ以
   上の値を timeout に指定すると "OverflowError" が発生します。

   バージョン 3.2 で追加.

このモジュールは多くのクラスを定義しています。それらは下記のセクション
で詳しく説明されます。

このモジュールのおおまかな設計は Java のスレッドモデルに基づいています
。とはいえ、 Java がロックと条件変数を全てのオブジェクトの基本的な挙動
にしているのに対し、 Python ではこれらを別個のオブジェクトに分けていま
す。 Python の "Thread" クラスがサポートしているのは Java の Thread ク
ラスの挙動のサブセットにすぎません; 現状では、優先度 (priority)やスレ
ッドグループがなく、スレッドの破壊 (destroy)、中断 (stop)、一時停止
(suspend)、復帰 (resume)、割り込み (interrupt) は行えません。 Java の
Thread クラスにおける静的メソッドに対応する機能が実装されている場合に
はモジュールレベルの関数になっています。

以下に説明するメソッドは全て原子的 (atomic) に実行されます。


スレッドローカルデータ
======================

スレッドローカルデータは、その値がスレッド固有のデータです。スレッドロ
ーカルデータを管理するには、単に "local" (あるいはそのサブクラス) のイ
ンスタンスを作成して、その属性に値を設定してください:

   mydata = threading.local()
   mydata.x = 1

インスタンスの値はスレッドごとに違った値になります。

class threading.local

   スレッドローカルデータを表現するクラス。

   詳細と例題については、 "_threading_local" モジュールのドキュメンテ
   ーション文字列を参照してください。


Thread オブジェクト
===================

"Thread" クラスは個別のスレッド中で実行される活動 (activity) を表現し
ます。活動を決める方法は 2 つあり、一つは呼び出し可能オブジェクトをコ
ンストラクタへ渡す方法、もう一つはサブクラスで "run()" メソッドをオー
バライドする方法です。 (コンストラクタを除く) その他のメソッドは一切サ
ブクラスでオーバライドしてはなりません。言い換えるならば、このクラスの
"__init__()" と "run()" メソッド *だけ* をオーバライドしてくださいとい
うことです。

ひとたびスレッドオブジェクトを生成すると、スレッドの "start()" メソッ
ドを呼び出して活動を開始しなければなりません。 "start()" メソッド はそ
れぞれのスレッドの "run()" メソッドを起動します。

スレッドの活動が始まると、スレッドは '生存中 (alive)' とみなされます。
スレッドは、通常 "run()" メソッドが終了するまで、もしくは捕捉されない
例外が送出されるまで生存中となります。 "is_alive()" メソッドは、スレッ
ドが生存中であるかどうか調べます。

スレッドは他のスレッドの "join()" メソッドを呼び出すことができます。こ
のメソッドは、 "join()" メソッドを呼ばれたスレッドが終了するまでメソッ
ドの呼び出し元のスレッドをブロックします。

スレッドは名前を持っています。名前はコンストラクタに渡すことができ、
"name" 属性を通して読み出したり変更したりできます。

"run()" メソッドが例外を発生させた場合、"threading.excepthook()" が呼
び出され、例外を処理します。デフォルトでは、"threading.excepthook()"
は "SystemExit" を黙殺します。

スレッドには "デーモンスレッド (daemon thread)" であるというフラグを立
てられます。 このフラグには、残っているスレッドがデーモンスレッドだけ
になった時に Python プログラム全体を終了させるという意味があります。フ
ラグの初期値はスレッドを生成したスレッドから継承します。フラグの値は
"daemon" プロパティまたは *daemon* コンストラクタ引数を通して設定でき
ます。

注釈:

  デーモンスレッドは終了時にいきなり停止されます。デーモンスレッドで使
  われたリソース (開いているファイル、データベースのトランザクションな
  ど) は適切に解放されないかもしれません。きちんと (gracefully) スレッ
  ドを停止したい場合は、スレッドを非デーモンスレッドにして、"Event" の
  ような適切なシグナル送信機構を使用してください。

スレッドには "主スレッド (main thread)" オブジェクトがあります。主スレ
ッドは Python プログラムを最初に制御していたスレッドです。主スレッドは
デーモンスレッドではありません。

"ダミースレッド (dummy thread)" オブジェクトを作成することができます。
ダミースレッドは、 "外来スレッド (alien thread)" に対応するスレッドオ
ブジェクトです。ダミースレッドは、 C コードから直接生成されたスレッド
のような、 "threading" モジュールの外で開始された処理スレッドです。 ダ
ミースレッドオブジェクトには限られた機能しかなく、常に生存中、かつデー
モンスレッドであるとみなされ、 "join()" できません。また、外来スレッド
の終了を検出するのは不可能なので、ダミースレッドは削除できません。

class threading.Thread(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)

   コンストラクタは常にキーワード引数を使って呼び出さなければなりませ
   ん。各引数は以下の通りです:

   *group* は "None" でなければなりません。将来 "ThreadGroup" クラスが
   実装されたときの拡張用に予約されている引数です。

   *target* は "run()" メソッドによって起動される呼び出し可能オブジェ
   クトです。デフォルトでは何も呼び出さないことを示す "None" になって
   います。

   *name*はスレッド名です。デフォルトでは、"Thread-*N*"(*N*は小さな10
   進数)、または*target*引数が指定された場合"Thread-*N*
   (target)"("target"は``target.__name__``)という形式でユニークな名前
   が構成される。

   *args* は *target* を呼び出すときの引数タプルです。デフォルトは
   "()" です。

   *kwargs* は *target* を呼び出すときのキーワード引数の辞書です。デフ
   ォルトは "{}" です。

   "None" でない場合、*daemon* はスレッドがデーモンかどうかを明示的に
   設定します。"None" の場合 (デフォルト)、デーモン属性は現在のスレッ
   ドから継承されます。

   サブクラスでコンストラクタをオーバライドした場合、必ずスレッドが何
   かを始める前に基底クラスのコンストラクタ ("Thread.__init__()") を呼
   び出しておかなくてはなりません。

   バージョン 3.10 で変更: *name* 引数が省略された場合、*target* 名を
   使用します。

   バージョン 3.3 で変更: *daemon* 引数が追加されました。

   start()

      スレッドの活動を開始します。

      このメソッドは、スレッドオブジェクトあたり一度しか呼び出してはな
      りません。 "start()" は、オブジェクトの "run()" メソッドが個別の
      処理スレッド中で呼び出されるように調整します。

      同じスレッドオブジェクトに対し、このメソッドを2回以上呼び出した
      場合、 "RuntimeError" を送出します。

   run()

      スレッドの活動をもたらすメソッドです。

      このメソッドはサブクラスでオーバライドできます。標準の "run()"
      メソッドでは、オブジェクトのコンストラクタの *target* 引数に呼び
      出し可能オブジェクトを指定した場合、 *args* および *kwargs* の位
      置引数およびキーワード引数とともに呼び出します。

   join(timeout=None)

      スレッドが終了するまで待機します。 このメソッドは、 "join()" を
      呼ばれたスレッドが正常終了あるいは処理されない例外によって終了す
      るか、オプションのタイムアウトが発生するまで、メソッドの呼び出し
      元のスレッドをブロックします。

      *timeout* 引数が存在して "None" 以外の場合、それは操作に対するタ
      イムアウト秒 (あるいは秒未満の端数) を表す浮動小数点数でなければ
      なりません。 "join()" は常に "None" を返すので、 "join()" の後に
      "is_alive()" を呼び出してタイムアウトしたかどうかを確認しなけれ
      ばなりません。もしスレッドがまだ生存中であれば、 "join()" はタイ
      ムアウトしています。

      *timeout* が指定されないかまたは "None" であるときは、この操作は
      スレッドが終了するまでブロックします。

      一つのスレッドに対して何度でも "join()" できます。

      現在のスレッドに対して "join()" を呼び出そうとすると、デッドロッ
      クを引き起こすため "RuntimeError" が送出されます。 スレッドが開
      始される前に "join()" を呼び出すことも同様のエラーのため、同じ例
      外が送出されます。

   name

      識別のためにのみ用いられる文字列です。名前には機能上の意味づけ
      (semantics) はありません。複数のスレッドに同じ名前をつけてもかま
      いません。名前の初期値はコンストラクタで設定されます。

   getName()
   setName()

      "name" に対する非推奨 getter/setter API; 代わりにプロパティを直
      接使用してください。

      バージョン 3.10 で非推奨.

   ident

      'スレッド識別子' 、または、スレッドが開始されていなければ "None"
      です。非ゼロの整数です。 "get_ident()" 関数を参照下さい。スレッ
      ド識別子は、スレッドが終了した後、新たなスレッドが生成された場合
      、再利用され得ます。スレッド識別子は、スレッドが終了した後でも利
      用できます。

   native_id

      The Thread ID ("TID") of this thread, as assigned by the OS
      (kernel). This is a non-negative integer, or "None" if the
      thread has not been started. See the "get_native_id()" function.
      This value may be used to uniquely identify this particular
      thread system-wide (until the thread terminates, after which the
      value may be recycled by the OS).

      注釈:

        Similar to Process IDs, Thread IDs are only valid (guaranteed
        unique system-wide) from the time the thread is created until
        the thread has been terminated.

      Availability: Requires "get_native_id()" function.

      バージョン 3.8 で追加.

   is_alive()

      スレッドが生存中かどうかを返します。

      このメソッドは、 "run()" メソッドが起動する直前から "run()" メソ
      ッドが終了する直後までの間 "True" を返します。モジュール関数
      "enumerate()" は、全ての生存中のスレッドのリストを返します。

   daemon

      このスレッドがデーモンスレッドか ("True") か否か ("False") を示
      すブール値。この値は "start()" の呼び出し前に設定されなければな
      りません。さもなければ "RuntimeError" が送出されます。初期値は生
      成側のスレッドから継承されます; メインスレッドはデーモンスレッド
      ではないので、メインスレッドで作成されたすべてのスレッドは、デフ
      ォルトで "daemon" = "False" になります。

      デーモンでない生存中のスレッドが全てなくなると、 Python プログラ
      ム全体が終了します。

   isDaemon()
   setDaemon()

      "daemon" に対する非推奨 getter/setter API; 代わりにプロパティを
      直接使用してください。

      バージョン 3.10 で非推奨.


Lock オブジェクト
=================

プリミティブロックとは、ロックが生じた際に特定のスレッドによって所有さ
れない同期プリミティブです。 Python では現在のところ拡張モジュール
"_thread" で直接実装されている最も低水準の同期プリミティブを使えます。

プリミティブロックは2つの状態、 "ロック" または "アンロック" がありま
す。ロックはアンロック状態で作成されます。ロックには基本となる二つのメ
ソッド、 "acquire()" と "release()" があります。ロックの状態がアンロッ
クである場合、 "acquire()" は状態をロックに変更して即座に処理を戻しま
す。 状態がロックの場合、 "acquire()" は他のスレッドが "release()" を
呼び出してロックの状態をアンロックに変更するまでブロックします。その後
、 "acquire()" 呼び出しは状態を再度ロックに設定してから処理を戻します
。 "release()" メソッドを呼び出すのはロック状態のときでなければなりま
せん; このメソッドはロックの状態をアンロックに変更して、即座に処理を戻
します。 アンロックの状態のロックを解放しようとすると "RuntimeError"
が送出されます。

ロックは コンテキストマネージメントプロトコル もサポートします。

複数のスレッドにおいて "acquire()" がアンロック状態への遷移を待ってい
るためにブロックが起きている時に "release()" を呼び出してロックの状態
をアンロックにすると、一つのスレッドだけが処理を進行できます。 どのス
レッドが処理を進行できるのかは定義されておらず、実装によって異なるかも
しれません。

全てのメソッドはアトミックに実行されます。

class threading.Lock

   プリミティブロック (primitive lock) オブジェクトを実装しているクラ
   スです。スレッドが一度ロックを獲得すると、それ以後のロック獲得の試
   みはロックが解放されるまでブロックします。どのスレッドでもロックを
   解放できます。

   "Lock" は実際にはファクトリ関数で、プラットフォームでサポートされる
   最も効率的なバージョンの具体的な Lock クラスのインスタンスを返すこ
   とに注意してください。

   acquire(blocking=True, timeout=- 1)

      ブロックあり、またはブロックなしでロックを獲得します。

      引数 *blocking* を "True" (デフォルト) に設定して呼び出した場合
      、ロックがアンロック状態になるまでブロックします。そしてそれをロ
      ック状態にしてから "True" を返します。

      引数 *blocking* の値を "False" にして呼び出すとブロックしません
      。*blocking* を "True" にして呼び出した場合にブロックするような
      状況では、直ちに "False" を返します。それ以外の場合には、ロック
      をロック状態にして "True" を返します。

      正の値に設定された浮動小数点の *timeout* 引数とともに起動された
      場合、ロックを得られなければ最大で *timeout* によって指定された
      秒数だけブロックします。*timeout* 引数の "-1" は無制限の待機を指
      定します。*blocking* が "False" の場合に *timeout* を指定するこ
      とは禁止されています。

      ロックを獲得すると "True" を、ロックを獲得できなかったとき (例え
      ば *timeout* が過ぎた場合) には "False" を返します。

      バージョン 3.2 で変更: 新しい *timeout* 引数。

      バージョン 3.2 で変更: Lock acquisition can now be interrupted
      by signals on POSIX if the underlying threading implementation
      supports it.

   release()

      ロックを解放します。これはロックを獲得したスレッドだけでなく、任
      意のスレッドから呼ぶことができます。

      ロックの状態がロックのとき、状態をアンロックにリセットして処理を
      戻します。他のスレッドがロックがアンロック状態になるのを待ってブ
      ロックしている場合、ただ一つのスレッドだけが処理を継続できるよう
      にします。

      アンロック状態のロックに対して呼び出された場合、"RuntimeError"
      が送出されます。

      戻り値はありません。

   locked()

      ロック状態のとき "True" を返します。


RLock オブジェクト
==================

再入可能ロック (reentrant lock) とは、同じスレッドが複数回獲得できるよ
うな同期プリミティブです。再入可能ロックの内部では、プリミティブロック
の使うロック／アンロック状態に加え、 "所有スレッド (owning thread)" と
"再帰レベル (recursion level)" という概念を用いています。ロック状態で
は何らかのスレッドがロックを所有しており、アンロック状態ではいかなるス
レッドもロックを所有していません。

このロックの状態をロックにするには、スレッドがロックの "acquire()" メ
ソッドを呼び出します。このメソッドはスレッドがロックを所有すると処理を
戻します。ロックの状態をアンロックにするには "release()" メソッドを呼
び出します。 "acquire()" / "release()" からなるペアの呼び出しはネスト
できます; 最後に呼び出した "release()" (最も外側の呼び出しペアの
"release()") だけがロックの状態をアンロックにリセットして、
"acquire()" でブロック中の別のスレッドの処理を進行させることができます
。

再入可能ロックは コンテキストマネージメントプロトコル もサポートします
。

class threading.RLock

   このクラスは再入可能ロックオブジェクトを実装します。再入可能ロック
   はそれを獲得したスレッドによって解放されなければなりません。いった
   んスレッドが再入可能ロックを獲得すると、同じスレッドはブロックされ
   ずにもう一度それを獲得できます ; そのスレッドは獲得した回数だけ解放
   しなければいけません。

   "RLock" は実際にはファクトリ関数で、プラットフォームでサポートされ
   る最も効率的なバージョンの具体的な RLock クラスのインスタンスを返す
   ことに注意してください。

   acquire(blocking=True, timeout=- 1)

      ブロックあり、またはブロックなしでロックを獲得します。

      引数なしで呼び出した場合: スレッドが既にロックを所有している場合
      、再帰レベルをインクリメントして即座に処理を戻します。それ以外の
      場合、他のスレッドがロックを所有していれば、そのロックの状態がア
      ンロックになるまでブロックします。その後、ロックの状態がアンロッ
      クになる (いかなるスレッドもロックを所有しない状態になる) と、ロ
      ックの所有権を獲得し、再帰レベルを 1 にセットして処理を戻します
      。ロックの状態がアンロックになるのを待っているスレッドが複数ある
      場合、その中の一つだけがロックの所有権を獲得できます。この場合、
      戻り値はありません。

      引数 *blocking* の値を "True" にして呼び出した場合、引数なしで呼
      び出したときと同じことを行ない、 "True" を返します。

      引数 *blocking* の値を "False" にして呼び出すとブロックしません
      。引数なしで呼び出した場合にブロックするような状況であった場合に
      は直ちに "False" を返します。それ以外の場合には、引数なしで呼び
      出したときと同じ処理を行い "True" を返します。

      正の値に設定された浮動小数点の *timeout* 引数とともに起動された
      場合、ロックを得られなければ最大で *timeout* によって指定された
      秒数だけブロックします。ロックを獲得した場合 "True" を返し、タイ
      ムアウトが過ぎた場合は "False" を返します。

      バージョン 3.2 で変更: 新しい *timeout* 引数。

   release()

      再帰レベルをデクリメントしてロックを解放します。デクリメント後に
      再帰レベルがゼロになった場合、ロックの状態をアンロック (いかなる
      スレッドにも所有されていない状態) にリセットし、ロックの状態がア
      ンロックになるのを待ってブロックしているスレッドがある場合にはそ
      の中のただ一つだけが処理を進行できるようにします。デクリメント後
      も再帰レベルがゼロでない場合、ロックの状態はロックのままで、呼び
      出し側のスレッドに所有されたままになります。

      呼び出し側のスレッドがロックを所有しているときにのみこのメソッド
      を呼び出してください。ロックの状態がアンロックの時にこのメソッド
      を呼び出すと、 "RuntimeError" が送出されます。

      戻り値はありません。


Condition オブジェクト
======================

条件変数 (condition variable) は、常にある種のロックに関連付けられてい
ます; このロックは明示的に渡すことも、デフォルトで生成させることもでき
ます。複数の条件変数で同じロックを共有しなければならない場合には、引渡
しによる関連付けが便利です。ロックは条件オブジェクトの一部です: それを
別々に扱う必要はありません。

条件変数は コンテキスト管理プロトコル に従います: "with" 文を使って囲
まれたブロックの間だけ関連付けられたロックを獲得することができます。
"acquire()" メソッドと "release()" メソッドは、さらに関連付けられたロ
ックの対応するメソッドを呼び出します。

他のメソッドは、関連付けられたロックを保持した状態で呼び出さなければな
りません。 "wait()" メソッドはロックを解放します。そして別のスレッドが
"notify()" または "notify_all()" を呼ぶことによってスレッドを起こすま
でブロックします。一旦起こされたなら、 "wait()" は再びロックを得て戻り
ます。タイムアウトを指定することも可能です。

"notify()" メソッドは条件変数待ちのスレッドを1つ起こします。
"notify_all()" メソッドは条件変数待ちの全てのスレッドを起こします。

注意: "notify()" と "notify_all()" はロックを解放しません; 従って、ス
レッドが起こされたとき、 "wait()" の呼び出しは即座に処理を戻すわけでは
なく、 "notify()" または "notify_all()" を呼び出したスレッドが最終的に
ロックの所有権を放棄したときに初めて処理を返すのです。

条件変数を使う典型的なプログラミングスタイルでは、何らかの共有された状
態変数へのアクセスを同期させるためにロックを使います; 状態変数が特定の
状態に変化したことを知りたいスレッドは、自分の望む状態になるまで繰り返
し "wait()" を呼び出します。その一方で、状態変更を行うスレッドは、前者
のスレッドが待ち望んでいる状態であるかもしれないような状態へ変更を行っ
たときに "notify()" や "notify_all()" を呼び出します。例えば、以下のコ
ードは無制限のバッファ容量のときの一般的な生産者-消費者問題です:

   # Consume one item
   with cv:
       while not an_item_is_available():
           cv.wait()
       get_an_available_item()

   # Produce one item
   with cv:
       make_an_item_available()
       cv.notify()

アプリケーションの条件をチェックする "while" ループは必須です。なぜな
ら、 "wait()" が任意の長時間の後で返り、 "notify()" 呼び出しを促した条
件がもはや真でないことがありえるからです。これはマルチスレッドプログラ
ミングに固有です。条件チェックを自動化するために "wait_for()" メソッド
を使うことができ、それはタイムアウトの計算を簡略化します:

   # Consume an item
   with cv:
       cv.wait_for(an_item_is_available)
       get_an_available_item()

"notify()" と "notify_all()" のどちらを使うかは、その状態の変化に興味
を持っている待ちスレッドが一つだけなのか、あるいは複数なのかで考えます
。例えば、典型的な生産者-消費者問題では、バッファに1つの要素を加えた場
合には消費者スレッドを 1 つしか起こさなくてかまいません。

class threading.Condition(lock=None)

   このクラスは条件変数 (condition variable) オブジェクトを実装します
   。条件変数を使うと、1つ以上のスレッドを別のスレッドの通知があるまで
   待機させておけます。

   *lock* に "None" でない値を指定した場合、その値は "Lock" または
   "RLock" オブジェクトでなければなりません。 この場合、 *lock* は根底
   にあるロックオブジェクトとして使われます。 それ以外の場合には、
   "RLock" オブジェクトを新しく作成して使います。

   バージョン 3.3 で変更: ファクトリ関数からクラスに変更されました。

   acquire(*args)

      根底にあるロックを獲得します。このメソッドは根底にあるロックの対
      応するメソッドを呼び出します。そのメソッドの戻り値を返します。

   release()

      根底にあるロックを解放します。このメソッドは根底にあるロックの対
      応するメソッドを呼び出します。戻り値はありません。

   wait(timeout=None)

      通知 (notify) を受けるか、タイムアウトするまで待機します。呼び出
      し側のスレッドがロックを獲得していないときにこのメソッドを呼び出
      すと "RuntimeError" が送出されます。

      このメソッドは根底にあるロックを解放し、他のスレッドが同じ条件変
      数に対して "notify()" または "notify_all()" を呼び出して現在のス
      レッドを起こすか、オプションのタイムアウトが発生するまでブロック
      します。一度スレッドが起こされると、再度ロックを獲得して処理を戻
      します。

      *timeout* 引数を指定して、 "None" 以外の値にする場合、タイムアウ
      トを秒 (または端数秒) を表す浮動小数点数でなければなりません。

      根底にあるロックが "RLock" である場合、 "release()" メソッドでは
      ロックは解放されません。というのも、ロックが再帰的に複数回獲得さ
      れている場合には、 "release()" によって実際にアンロックが行われ
      ないかもしれないからです。その代わり、ロックが再帰的に複数回獲得
      されていても確実にアンロックを行える "RLock" クラスの内部インタ
      ーフェースを使います。その後ロックを再獲得する時に、もう一つの内
      部インターフェースを使ってロックの再帰レベルを復帰します。

      与えられた *timeout* が過ぎていなければ返り値は "True" です。タ
      イムアウトした場合には "False" が返ります。

      バージョン 3.2 で変更: 以前は、このメソッドは常に "None" を返し
      ていました。

   wait_for(predicate, timeout=None)

      条件が真と判定されるまで待ちます。 *predicate* は呼び出し可能オ
      ブジェクトでなければならず、その結果はブール値として解釈されます
      。 最大の待ち時間を指定する *timeout* を与えることができます。

      このユーティリティメソッドは、述語が満たされるかタイムアウトが発
      生するまで "wait()" を繰り返し呼び出す場合があります。戻り値は述
      語の最後の戻り値で、もしメソッドがタイムアウトすれば、 "False"
      と評価されます。

      タイムアウト機能を無視すれば、このメソッドの呼び出しは以下のよう
      に書くのとほぼ等価です:

         while not predicate():
             cv.wait()

      したがって、 "wait()" と同じルールが適用されます: 呼び出された時
      にロックを保持していなければならず、戻るときにロックが再度獲得さ
      れます。述語はロックを保持した状態で評価されます。

      バージョン 3.2 で追加.

   notify(n=1)

      デフォルトで、この条件変数を待っている1つのスレッドを起こします
      。 呼び出し側のスレッドがロックを獲得していないときにこのメソッ
      ドを呼び出すと "RuntimeError" が送出されます。

      何らかの待機中スレッドがある場合、そのうち *n* スレッドを起こし
      ます。待機中のスレッドがなければ何もしません。

      現在の実装では、少なくとも *n* スレッドが待機中であれば、ちょう
      ど *n* スレッドを起こします。とはいえ、この挙動に依存するのは安
      全ではありません。将来、実装の最適化によって、複数のスレッドを起
      こすようになるかもしれないからです。

      注意: 起こされたスレッドは実際にロックを再獲得できるまで
      "wait()" 呼び出しから戻りません。 "notify()" はロックを解放しな
      いので、 "notify()" 呼び出し側は明示的にロックを解放しなければな
      りません。

   notify_all()

      この条件を待っているすべてのスレッドを起こします。このメソッドは
      "notify()" のように動作しますが、 1 つではなくすべての待ちスレッ
      ドを起こします。呼び出し側のスレッドがロックを獲得していない場合
      、 "RuntimeError" が送出されます。

      関数``notifyAll``はこの関数の非推奨エイリアスです。


Semaphore オブジェクト
======================

セマフォ (semaphore) は、計算機科学史上最も古い同期プリミティブの一つ
で、草創期のオランダ計算機科学者 Edsger W. Dijkstra によって発明されま
した (彼は "acquire()" と "release()" の代わりに "P()" と "V()" を使い
ました)。

セマフォは "acquire()" でデクリメントされ "release()" でインクリメント
されるような内部カウンタを管理します。 カウンタは決してゼロより小さく
はなりません; "acquire()" は、カウンタがゼロになっている場合、他のスレ
ッドが "release()" を呼び出すまでブロックします。

セマフォは コンテキストマネージメントプロトコル もサポートします。

class threading.Semaphore(value=1)

   このクラスはセマフォ (semaphore) オブジェクトを実装します。セマフォ
   は、 "release()" を呼び出した数から "acquire()" を呼び出した数を引
   き、初期値を足した値を表す極小のカウンタを管理します。 "acquire()"
   メソッドは、カウンタの値を負にせずに処理を戻せるまで必要ならば処理
   をブロックします。 *value* を指定しない場合、デフォルトの値は 1 に
   なります。

   オプションの引数には、内部カウンタの初期値を指定します。デフォルト
   は "1" です。与えられた *value* が 0 より小さい場合、 "ValueError"
   が送出されます。

   バージョン 3.3 で変更: ファクトリ関数からクラスに変更されました。

   acquire(blocking=True, timeout=None)

      セマフォを獲得します。

      When invoked without arguments:

      * If the internal counter is larger than zero on entry,
        decrement it by one and return "True" immediately.

      * If the internal counter is zero on entry, block until awoken
        by a call to "release()".  Once awoken (and the counter is
        greater than 0), decrement the counter by 1 and return "True".
        Exactly one thread will be awoken by each call to "release()".
        The order in which threads are awoken should not be relied on.

      *blocking* を "False" にして呼び出すとブロックしません。引数なし
      で呼び出した場合にブロックするような状況であった場合には直ちに
      "False" を返します。それ以外の場合には、引数なしで呼び出したとき
      と同じ処理を行い "True" を返します。

      "None" 以外の *timeout* で起動された場合、最大で *timeout* 秒ブ
      ロックします。 acquire が その間隔の間で完了しなかった場合は
      "False" が返ります。そうでなければ "True" が返ります。

      バージョン 3.2 で変更: 新しい *timeout* 引数。

   release(n=1)

      内部カウンタを *n* インクリメントして、セマフォを解放します。
      "release()" 処理に入ったときにカウンタがゼロであり、カウンタの値
      がゼロより大きくなるのを待っている別のスレッドがあった場合、それ
      らのスレッドから *n* 個を起こします。

      バージョン 3.9 で変更: 複数の待機中のスレッドを一度に解放する
      *n* パラメータを追加しました。

class threading.BoundedSemaphore(value=1)

   有限セマフォ (bounded semaphore) オブジェクトを実装しているクラスで
   す。有限セマフォは、現在の値が初期値を超過しないようチェックを行い
   ます。超過を起こした場合、 "ValueError" を送出します。たいていの場
   合、セマフォは限られた容量のリソースを保護するために使われるもので
   す。従って、あまりにも頻繁なセマフォの解放はバグが生じているしるし
   です。 *value* を指定しない場合、デフォルトの値は 1 になります。

   バージョン 3.3 で変更: ファクトリ関数からクラスに変更されました。


"Semaphore" の例
----------------

セマフォはしばしば、容量に限りのある資源、例えばデータベースサーバなど
を保護するために使われます。リソースが固定の状況では、常に有限セマフォ
を使わなければなりません。主スレッドは、作業スレッドを立ち上げる前にセ
マフォを初期化します:

   maxconnections = 5
   # ...
   pool_sema = BoundedSemaphore(value=maxconnections)

作業スレッドは、ひとたび立ち上がると、サーバへ接続する必要が生じたとき
にセマフォの "acquire()" および "release()" メソッドを呼び出します:

   with pool_sema:
       conn = connectdb()
       try:
           # ... use connection ...
       finally:
           conn.close()

有限セマフォを使うと、セマフォを獲得回数以上に解放してしまうというプロ
グラム上の間違いを見逃しにくくします。


Event オブジェクト
==================

イベントは、あるスレッドがイベントを発信し、他のスレッドはそれを待つと
いう、スレッド間で通信を行うための最も単純なメカニズムの一つです。

イベントオブジェクトは内部フラグを管理します。このフラグは "set()" メ
ソッドで値を true に、 "clear()" メソッドで値を false にリセットします
。 "wait()" メソッドはフラグが true になるまでブロックします。

class threading.Event

   イベントオブジェクトを実装しているクラスです。イベントは "set()" メ
   ソッドを使うと "True" に、 "clear()" メソッドを使うと "False" にセ
   ットされるようなフラグを管理します。 "wait()" メソッドは、全てのフ
   ラグが true になるまでブロックするようになっています。フラグの初期
   値は false です。

   バージョン 3.3 で変更: ファクトリ関数からクラスに変更されました。

   is_set()

      内部フラグが真のとき "True" を返します。

      メソッド "isSet" はこのメソッドの非推奨エイリアスです。

   set()

      内部フラグの値を true にセットします。フラグの値が true になるの
      を待っている全てのスレッドを起こします。一旦フラグが true になる
      と、スレッドが "wait()" を呼び出しても全くブロックしなくなります
      。

   clear()

      内部フラグの値を false にリセットします。以降は、 "set()" を呼び
      出して再び内部フラグの値を true にセットするまで、 "wait()" を呼
      び出したスレッドはブロックするようになります。

   wait(timeout=None)

      内部フラグの値が true になるまでブロックします。 "wait()" 処理に
      入った時点で内部フラグの値が true であれば、直ちに処理を戻します
      。そうでない場合、他のスレッドが "set()" を呼び出してフラグの値
      を true にセットするか、オプションのタイムアウトが発生するまでブ
      ロックします。

      *timeout* 引数を指定して、 "None" 以外の値にする場合、タイムアウ
      トを秒 (または端数秒) を表す浮動小数点数でなければなりません。

      このメソッドは、wait 呼び出しの前あるいは wait が開始した後に、
      内部フラグが true にセットされている場合に限り "True" を返します
      。したがって、タイムアウトが与えられて操作がタイムアウトした場合
      を除き常に "True" を返します。

      バージョン 3.1 で変更: 以前は、このメソッドは常に "None" を返し
      ていました。


Timer オブジェクト
==================

このクラスは、一定時間経過後に実行される活動、すなわちタイマ活動を表現
します。 "Timer" は "Thread" のサブクラスであり、自作のスレッドを構築
した一例でもあります。

タイマは "start()" メソッドを呼び出すとスレッドとして作動し始めします
。 (活動を開始する前に) "cancel()" メソッドを呼び出すと、タイマを停止
できます。タイマが活動を実行するまでの待ち時間は、ユーザが指定した待ち
時間と必ずしも厳密には一致しません。

例えば:

   def hello():
       print("hello, world")

   t = Timer(30.0, hello)
   t.start()  # after 30 seconds, "hello, world" will be printed

class threading.Timer(interval, function, args=None, kwargs=None)

   *interval* 秒後に引数 *args* キーワード引数 *kwargs* で *function*
   を実行するようなタイマを生成します。*args*が ``None`` (デフォルト)
   なら空のリストが使用されます。*kwargs* が "None" (デフォルト) なら
   空の辞書が使用されます。

   バージョン 3.3 で変更: ファクトリ関数からクラスに変更されました。

   cancel()

      タイマをストップして、その動作の実行をキャンセルします。このメソ
      ッドはタイマがまだ活動待ち状態にある場合にのみ動作します。


バリアオブジェクト
==================

バージョン 3.2 で追加.

このクラスは、互いを待つ必要のある固定の数のスレッドで使用するための単
純な同期プリミティブを提供します。それぞれのスレッドは "wait()" メソッ
ドを呼ぶことによりバリアを通ろうとしてブロックします。すべてのスレッド
がそれぞれの "wait()" メソッドを呼び出した時点で、すべてのスレッドが同
時に解放されます。

バリアは同じ数のスレッドに対して何度でも再利用することができます。

例として、クライアントとサーバの間でスレッドを同期させる単純な方法を紹
介します:

   b = Barrier(2, timeout=5)

   def server():
       start_server()
       b.wait()
       while True:
           connection = accept_connection()
           process_server_connection(connection)

   def client():
       b.wait()
       while True:
           connection = make_connection()
           process_client_connection(connection)

class threading.Barrier(parties, action=None, timeout=None)

   *parties* 個のスレッドのためのバリアオブジェクトを作成します。
   *action* は、もし提供されるなら呼び出し可能オブジェクトで、スレッド
   が解放される時にそのうちの1つによって呼ばれます。 *timeout* は、
   "wait()" メソッドに対して none が指定された場合のデフォルトのタイム
   アウト値です。

   wait(timeout=None)

      バリアを通ります。バリアに対するすべてのスレッドがこの関数を呼ん
      だ時に、それらは同時にすべて解放されます。*timeout* が提供される
      場合、それはクラスコンストラクタに渡された値に優先して使用されま
      す。

      返り値は 0 から *parties* -- 1 の範囲の整数で、それぞれのスレッ
      ドに対して異なります。これは、特別な後始末 (housekeeping) を行う
      スレッドを選択するために使用することができます。例えば:

         i = barrier.wait()
         if i == 0:
             # Only one thread needs to print this
             print("passed the barrier")

      *action* がコンストラクタに渡されていれば、スレッドのうちの1つが
      解放される前にそれを呼び出します。万一この呼び出しでエラーが発生
      した場合、バリアは broken な状態に陥ります。

      この呼び出しがタイムアウトする場合、バリアは broken な状態に陥り
      ます。

      スレッドが待っている間にバリアが broken になるかリセットされた場
      合、このメソッドは "BrokenBarrierError" 例外を送出するかもしれま
      せん。

   reset()

      バリアをデフォルトの空の状態に戻します。そのバリアの上で待ってい
      るすべてのスレッドは "BrokenBarrierError" 例外を受け取ります。

      状態が未知の他のスレッドがある場合、この関数を使用するのに何らか
      の外部同期を必要とするかもしれないことに注意してください。バリア
      が broken な場合、単にそれをそのままにして新しいものを作成する方
      がよいでしょう。

   abort()

      バリアを broken な状態にします。これによって、現在または将来の
      "wait()" 呼び出しが "BrokenBarrierError" とともに失敗するように
      なります。これを使うと、例えばスレッドが異常終了する必要がある場
      合にアプリケーションがデッドロックするのを避けることができます。

      スレッドのうちの1つが返ってこないことに対して自動的に保護するよ
      うに、単純に常識的な *timeout* 値でバリアを作成することは望まし
      いかもしれません。

   parties

      バリアを通るために要求されるスレッドの数。

   n_waiting

      現在バリアの中で待っているスレッドの数。

   broken

      バリアが broken な状態である場合に "True" となるブール値。

exception threading.BrokenBarrierError

   "Barrier" オブジェクトがリセットされるか broken な場合に、この例外
   ("RuntimeError" のサブクラス) が送出されます。


"with" 文でのロック・条件変数・セマフォの使い方
===============================================

このモジュールのオブジェクトのうち "acquire()" メソッドと "release()"
メソッドを備えているものは全て "with" 文のコンテキストマネージャ とし
て使うことができます。 "with" 文のブロックに入るときに "acquire()" メ
ソッドが 呼び出され、ブロック脱出時には "release()" メソッドが呼ばれま
す。したがって、次のコード:

   with some_lock:
       # do something...

は、以下と同じです

   some_lock.acquire()
   try:
       # do something...
   finally:
       some_lock.release()

現在のところ、 "Lock" 、 "RLock" 、 "Condition" 、 "Semaphore" 、
"BoundedSemaphore" を "with" 文のコンテキストマネージャとして使うこと
ができます。
