16.2. "threading" --- 高水準のスレッドインタフェース
****************************************************

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

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

このモジュールでは、高水準のスレッドインタフェースをより低水準な
"thread" モジュールの上に構築しています。 "mutex" と "Queue" モジュー
ルのドキュメントも参照下さい。

また、 "thread" がないために "threading" を使えないような状況向けに
"dummy_threading" を提供しています。

注釈: Python 2.6 からこのモジュールは Java のスレッディング API の影
  響を受 けた "camelCase" のプロパティを置き換える **PEP 8** に準拠し
  たエイリ アスを提供します。この更新された API は "multiprocessing"
  モジュール のものと互換です。しかしながら、 "camelCase" の名称の廃止
  の予定は決 まっておらず、 Python 2.x と 3.x の両方でサポートされ続け
  ます。

注釈: Python 2.5 から, 幾つかの Thread のメソッドは間違った呼び出し
  に対し て "AssertionError" の代わりに "RuntimeError" を返します。

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

このモジュールでは以下のような関数とオブジェクトを定義しています:

threading.active_count()
threading.activeCount()

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

   バージョン 2.6 で変更: 新たに "active_count()" として使えるようにな
   りました。

threading.Condition()

   新しい条件変数 (condition variable) オブジェクトを返すファクトリ関
   数です。条件変数を使うと、ある複数のスレッドを別のスレッドの通知が
   あるまで待機させられます。

   Condition オブジェクト を参照してください。

threading.current_thread()
threading.currentThread()

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

   バージョン 2.6 で変更: 新たに "current_thread()" として使えるように
   なりました。

threading.enumerate()

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

threading.Event()

   新たなイベントオブジェクトを返すファクトリ関数です。イベントは
   "set()" メソッドを使うと "True" に、 "clear()" メソッドを使うと
   "False" にセットされるようなフラグを管理します。 "wait()" メソッド
   は、全てのフラグが真になるまでブロックするようになっています。

   Event オブジェクト を参照してください。

class threading.local

   スレッドローカルデータ (thread-local data) を表現するためのクラスで
   す。スレッドローカルデータとは、値が各スレッド固有になるようなデー
   タです。スレッドローカルデータを管理するには、 "local" (または
   "local" のサブクラス) のインスタンスを作成して、その属性に値を代入
   します

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

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

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

   バージョン 2.4 で追加.

threading.Lock()

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

   Lock オブジェクト を参照してください。

threading.RLock()

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

   RLock オブジェクト を参照してください。

threading.Semaphore([value])

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

   Semaphore オブジェクト を参照してください。

threading.BoundedSemaphore([value])

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

class threading.Thread

   処理中のスレッドを表すクラスです。このクラスは制限のある範囲内で安
   全にサブクラス化できます。

   Thread オブジェクト を参照してください。

class threading.Timer

   指定時間経過後に関数を実行するスレッドです。

   Timer オブジェクト を参照してください。

threading.settrace(func)

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

   バージョン 2.3 で追加.

threading.setprofile(func)

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

   バージョン 2.3 で追加.

threading.stack_size([size])

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

   バージョン 2.5 で追加.

exception threading.ThreadError

   下記で記述するスレッド関連の様々なエラーで送出されます。多くのイン
   ターフェイスが "ThreadError" ではなく "RuntimeError" を使っているこ
   とに注意してください。

オブジェクトの詳細なインターフェースを以下に説明します。

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

   *name* はスレッドの名前です。デフォルトでは、 *N* を小さな 10 進数
   として、 "Thread- *N*" という形式の一意な名前を生成します。

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

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

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

   start()

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

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

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

   run()

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

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

   join([timeout])

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

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

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

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

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

   name

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

      バージョン 2.6 で追加.

   getName()
   setName()

      "name" の、Python 2.6 以前の API です。

   ident

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

      バージョン 2.6 で追加.

   is_alive()
   isAlive()

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

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

      バージョン 2.6 で変更: 新たに "is_alive()" として使えるようにな
      りました。

   daemon

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

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

      バージョン 2.6 で追加.

   isDaemon()
   setDaemon()

      "daemon" の、Python 2.6 以前の API です。


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

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

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

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

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

Lock.acquire([blocking])

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

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

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

Lock.release()

   ロックを解放します。

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

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

   戻り値はありません。


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

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

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

RLock.acquire([blocking=1])

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

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

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

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

RLock.release()

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

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

   戻り値はありません。


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

条件変数 (condition variable) は常にある種のロックに関連付けられていま
す; 条件変数に関連付けるロックは明示的に引き渡したり、デフォルトで生成
させたりできます。 (複数の条件変数で同じロックを共有するような場合には
、引渡しによる関連付けが便利です。)

条件変数には、 "acquire()" メソッドおよび "release()" があり、関連付け
されているロックの対応するメソッドを呼び出すようになっています。また、
"wait()", "notify()", "notifyAll()" といったメソッドがあります。これら
三つのメソッドを呼び出せるのは、呼び出し手のスレッドがロックを獲得して
いる時だけです。そうでない場合は "RuntimeError" が送出されます。

"wait()" メソッドは現在のスレッドのロックを解放し、他のスレッドが同じ
条件変数に対して "notify()" または "notifyAll()" を呼び出して現在のス
レッドを起こすまでブロックします。一度起こされると、再度ロックを獲得し
て処理を戻します。 "wait()" にはタイムアウトも設定できます。

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

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

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

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

   # Produce one item
   cv.acquire()
   make_an_item_available()
   cv.notify()
   cv.release()

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

class threading.Condition([lock])

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

   acquire(*args)

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

   release()

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

   wait([timeout])

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

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

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

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

   notify(n=1)

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

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

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

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

   notify_all()
   notifyAll()

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

      バージョン 2.6 で変更: 新たに "notify_all()" として使えるように
      なりました。


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

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

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

class threading.Semaphore([value])

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

   acquire([blocking])

      セマフォを獲得します。

      引数なしで呼び出した場合: "acqure()" 処理に入ったときに内部カウ
      ンタがゼロより大きければ、カウンタを 1 デクリメントして即座に処
      理を戻します。 "acqure()" 処理に入ったときに内部カウンタがゼロの
      場合、他のスレッドが "release()" を呼び出してカウンタをゼロより
      大きくするまでブロックします。この処理は、適切なインターロック
      (interlock) を介して行い、複数の "acquire()" 呼び出しがブロック
      された場合、 "release()" が正確に一つだけを起こせるようにします
      。この実装はランダムに一つ選択するだけでもよいので、ブロックされ
      たスレッドがどの起こされる順番に依存してはなりません。この場合、
      戻り値はありません。

      *blocking* 引数の値を真にした場合、引数なしで呼び出した場合と同
      じ処理を行って真を返します。

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

   release()

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


16.2.5.1. "Semaphore" の例
--------------------------

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

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

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

   pool_sema.acquire()
   conn = connectdb()
   ... use connection ...
   conn.close()
   pool_sema.release()

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


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

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

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

class threading.Event

   内部フラグの初期値は偽です。

   is_set()
   isSet()

      内部フラグの値が true である場合にのみ true を返します。

      バージョン 2.6 で変更: 新たに "is_set()" として使えるようになり
      ました。

   set()

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

   clear()

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

   wait([timeout])

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

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

      このメソッドは終了時の内部フラグを返します。 timeout が指定され
      て、操作がタイムアウトしたとき以外は、 "True" を返すはずです。

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


16.2.7. 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=[], kwargs={})

   *interval* 秒後に *function* を引数 *args* 、キーワード引数
   *kwargs* つきで実行するようなタイマを生成します。

   cancel()

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


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

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

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

   import threading

   some_rlock = threading.RLock()

   with some_rlock:
       print "some_rlock is locked while this executes"


16.2.9. スレッド化されたコード中でのImport
==========================================

スレッドセーフなimportのためには、継承の制限に起因する、ふたつの重要な
制約があります。

* ひとつ目は、主とするモジュール以外では、importが新しいスレッドを生
  成 しないようになっていなければなりません。そして、そのスレッドを待
  たな ければなりません。この制約を守らない場合、生成されたスレッドが
  直接的 、または、間接的にモジュールをimportしようとした際に、デッド
  ロックを 引き起こす可能性があります。

* ふたつ目は、全てのimportが、インタープリターが自身を終了させる前に
  完 了しなければなりません。これは、最も簡単な方法としては、threading
  モ ジュールを通して生成される非デーモンからのみimportを実行すること
  で達 成できます。デーモンスレッド、および、直接、threadモジュールか
  ら生成 されたスレッドは、インタープリター終了後にimportを実行しない
  ようにす る、別の同期の仕組みを必要とします。この制約を守らない場合
  、 intermittent (間歇) 例外を引き起こし、インタープリターのシャット
  ダウ ン中にクラッシュする可能性があります。 (後から実行されるimport
  は、す でにアクセス可能でなくなった領域にアクセスしようとするためで
  す)
