# 4 `thread` -- マルチスレッドのコントロール

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

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

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

exception `error`
  スレッド特有のエラーで送出されます。

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

`start_new_thread`( | function, args[, kwargs])

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

`interrupt_main`( | )

  メインスレッドで KeyboardInterrupt を送出します。サブスレッドは この関数を使ってメインスレッドに割り込みをかけることができます。 バージョン 2.3 で 新たに追加 された仕様です。

`exit`( | )

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

`allocate_lock`( | )

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

`get_ident`( | )

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

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

`acquire`( | [waitflag])

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

`release`( | )

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

`locked`( | )

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

Caveats:

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

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

- I/O待ちをブロックするかもしれない全ての組込み関数が、 他のスレッドの走行を許すわけではありません。 (ほとんどの一般的なもの (`time.sleep()`, `file.read()`, `select.select()`)は期待通りに働きます。)

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

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

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