17.9. "_thread" --- 低水準の スレッド API
*****************************************

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

このモジュールはマルチスレッド (別名 *軽量プロセス* (*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

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

   バージョン 3.3 で変更: 現在は組み込みの "RuntimeError" の別名です。

_thread.LockType

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

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

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

_thread.interrupt_main()

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

_thread.exit()

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

_thread.allocate_lock()

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

_thread.get_ident()

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

_thread.stack_size([size])

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

_thread.TIMEOUT_MAX

   "Lock.acquire()" の *timeout* 引数に許される最大値です。これ以上の
   値を timeout に指定すると "OverflowError" を発生させます。

   バージョン 3.2 で追加.

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

lock.acquire(waitflag=1, timeout=-1)

   オプションの引数なしで使用すると、このメソッドは他のスレッドがロッ
   クしているかどうかにかかわらずロックを獲得します。ただし、他のスレ
   ッドがすでにロックしている場合には解除されるまで待ってからロックを
   獲得します (同時にロックを獲得できるスレッドはひとつだけであり、こ
   れこそがロックの存在理由です)。

   整数の引数 *waitflag* を指定すると、その値によって動作が変わります
   。引数が "0" のときは、待たずにすぐ獲得できる場合にだけロックを獲得
   します。"0" 以外の値を与えると、先の例と同様、ロックの状態にかかわ
   らず獲得をおこないます。

   *timeout* 引数に正の float 値が指定された場合、返る前に待つ最大の時
   間を秒数で指定します。負の *timeout* 引数は無制限に待つことを指定し
   ます。*waitflag* が 0 の時は *timeout* を指定することはできません。

   なお、ロックを獲得できた場合は "True"、できなかった場合は "False"
   を返します。

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

   バージョン 3.2 で変更: POSIX ではロックの取得がシグナルに割り込まれ
   るようになりました。

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" 例外は、ロックが獲得された後に発生します。

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

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