16.3. "thread" --- マルチスレッドのコントロール
***********************************************

注釈: Python 3 では "thread" モジュールは "_thread" に改名されました
  。 *2to3* ツールは、 3 コードへの変換時に、自動的に import 宣言を適
  合さ せます。しかしながら、上位の "threading" モジュールを使うことを
  検討 して下さい。

このモジュールはマルチスレッド (別名 *軽量プロセス* (*light-weight
processes*)または *タスク* (*tasks*)) に用いられる低レベルプリミティブ
を提供します --- グローバルデータ空間を共有するマルチスレッドを制御し
ます。同期のための単純なロック (別名 *mutexes* またはバイナリセマフォ
(*binary semaphores*))が提供されています。 "threading" モジュールは、
このモジュール上で、より使い易く高級なスレッディングの API を提供しま
す。

このモジュールはオプションです。 Windows, Linux, SGI IRIX, Solaris 2.x
、そして同じようなPOSIXスレッド (別名 "pthread" ) 実装のシステム上でサ
ポートされます。 "thread" を使用することのできないシステムでは、
"dummy_thread" が用意されています。 "dummy_thread" はこのモジュールと
同じインターフェースを持ち、置き換えて使用することができます。

定数と関数は以下のように定義されています:

exception thread.error

   スレッド特有の例外です。

thread.LockType

   これはロックオブジェクトのタイプです。

thread.start_new_thread(function, args[, kwargs])

   新しいスレッドを開始して、そのIDを返します。スレッドは引数リスト
   *args* (タプルでなければなりません)の関数 *function* を実行します。
   オプション引数 *kwargs* はキーワード引数の辞書を指定します。関数が
   戻るとき、スレッドは黙って終了します。関数が未定義の例外でターミネ
   ートしたとき、スタックトレースが表示され、そしてスレッドが終了しま
   す (しかし他のスレッドは走り続けます)。

thread.interrupt_main()

   メインスレッドで "KeyboardInterrupt" を送出します。サブスレッドはこ
   の関数を使ってメインスレッドに割り込みをかけることができます。

   バージョン 2.3 で追加.

thread.exit()

   "SystemExit" を送出します。それが捕えられないときは、黙ってスレッド
   を終了させます。

thread.allocate_lock()

   新しいロックオブジェクトを返します。ロックのメソッドはこの後に記述
   されます。ロックは初期状態としてアンロック状態です。

thread.get_ident()

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

thread.stack_size([size])

   新しいスレッドが作られる際に使われるスレッドのスタックサイズを返し
   ます。オプションの *size* 引数は次に作られるスレッドに対するスタッ
   クサイズを指定するものですが、 0 (プラットフォームまたは設定された
   デフォルト) または少なくとも 32,768 (32kB) であるような正の整数でな
   ければなりません。 *size* に指定がなければ 0 が使われます。もしスタ
   ックサイズの変更がサポートされていなければ "ThreadError" が送出され
   ます。また指定されたスタックサイズが条件を満たしていなければ
   "ValueError" が送出されスタックサイズは変更されないままになります。
   32kB は今のところインタプリタ自体に十分なスタックスペースを保証する
   ための値としてサポートされる最小のスタックサイズです。プラットフォ
   ームによってはスタックサイズの値に固有の制限が課されることもありま
   す。たとえば 32kB より大きな最小スタックサイズを要求されたり、シス
   テムメモリサイズの倍数の割り当てを要求されるなどです - より詳しい情
   報はプラットフォームごとの文書で確認してください (4kB ページは一般
   的ですので、情報が見当たらないときには 4096 の倍数を指定しておくと
   いいかもしれません)。利用可能: Windows, POSIX スレッドのあるシステ
   ム。

   バージョン 2.5 で追加.

ロックオブジェクトは次のようなメソッドを持っています:

lock.acquire([waitflag])

   オプションの引数なしで使用すると、このメソッドは他のスレッドがロッ
   クしているかどうかにかかわらずロックを獲得します。ただし、他のスレ
   ッドがすでにロックしている場合には解除されるまで待ってからロックを
   獲得します (同時にロックを獲得できるスレッドはひとつだけであり、こ
   れこそがロックの存在理由です)。整数の引数 *waitflag* を指定すると、
   その値によって動作が変わります。引数が "0" のときは、待たずにすぐ獲
   得できる場合にだけロックを獲得します。 "0" 以外の値を与えると、先の
   例と同様、ロックの状態にかかわらず獲得をおこないます。なお、ロック
   を獲得すると "True" 、できなかったときには "False" を返します。

lock.release()

   ロックを解放します。そのロックは既に獲得されたものでなければなりま
   せんが、しかし同じスレッドによって獲得されたものである必要はありま
   せん。

lock.locked()

   ロックの状態を返します: 同じスレッドによって獲得されたものなら
   "True" 、違うのなら "False" を返します。

これらのメソッドに加えて、ロックオブジェクトは "with" 文を通じて以下の
例のように使うこともできます。

   import thread

   a_lock = thread.allocate_lock()

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

**警告:**

* スレッドは割り込みと奇妙な相互作用をします: "KeyboardInterrupt" 例
  外 は任意のスレッドによって受け取られます。 ("signal" モジュールが利
  用 可能なとき、割り込みは常にメインスレッドへ行きます。)

* "sys.exit()" を呼び出す、あるいは "SystemExit" 例外を送出すること
  は 、 "thread.exit()" を呼び出すことと同じです。

* ロックの "acquire()" メソッドに割り込むことはできません ---
  "KeyboardInterrupt" 例外は、ロックが獲得された後に発生します。

* メインスレッドが終了したとき、他のスレッドが生き残るかどうかは、シ
  ス テムに依存します。ネイティブスレッド実装を使う SGI, IRIX では生き
  残 ります。その他の多くのシステムでは、 "try" ... "finally" 節や、オ
  ブ ジェクトデストラクタを実行せずに終了されます。

* メインスレッドが終了したとき、それの通常のクリーンアップは行なわれ
  ず 、 ("try" ... "finally" 節が尊重されることは除きます)、標準 I/O
  ファ イルはフラッシュされません。
