16.2. threading — 高水準のスレッドインタフェース — Python 2.7ja1 documentation

### ナビゲーション

- 索引
- モジュール |
- 次へ |
- 前へ |
- Python 2.7ja1 documentation »
- Python 標準ライブラリ »
- 16. オプションのオペレーティングシステムサービス »

# 16.2. `threading` — 高水準のスレッドインタフェース

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

参考

最新バージョンの threading module Python source code

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

`threading.` `active_count`()
`threading.` `activeCount`()

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

`threading.` `Condition`()

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

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

`threading.` `current_thread`()
`threading.` `currentThread`()

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

`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.settrace()` に渡されます。

  バージョン 2.3 で追加.

`threading.` `stack_size`([size])

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

  バージョン 2.5 で追加.

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

このモジュールのおおまかな設計は 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` 属性を通して設定できます。

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

“ダミースレッド (dumm 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()` を呼び出そうとしても、同じ例外が送出されます。

  `getName`()
  `setNmae`()

    `name` に対応する、旧式の API です。

  `name`

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

  `ident`

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

    バージョン 2.6 で追加.

  `is_alive`()
  `isAlive`()

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

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

  `isDaemon`()
  `setDaemon`()

    `daemon` に対応する、旧式の API です。

  `daemon`

    スレッドのデーモンフラグです。このフラグは `start()` の呼び出し前に設定されなければなりません。さもなくば、 `RuntimeError` が送出されます。

    初期値は生成側のスレッドから継承されます。

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

## 16.2.2. Lock オブジェクト

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

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

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

全てのメソッドは原子的に実行されます。

`Lock.` `acquire`([blocking])

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

  引数なしで呼び出した場合、ロックの状態がアンロックになるまでブロックし、その後状態をロックにセットして真値を返します。

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

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

`Lock.` `release`()

  ロックを解放します。

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

  ロックがアンロック状態のとき、このメソッドを呼び出してはなりません。

  戻り値はありません。

## 16.2.3. RLock オブジェクト

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

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

`RLock.` `acquire`([blocking=1])

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

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

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

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

`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`()

    この条件変数を待っているスレッドがあれば、そのスレッドを起こします。呼び出し手のスレッドがロックを獲得していないときにこのメソッドを呼び出すと `RuntimeError` が送出されます。

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

    現在の実装では、待機中のメソッドをただ一つだけ起こします。とはいえ、この挙動に依存するのは安全ではありません。将来、実装の最適化によって、複数のスレッドを起こすようになるかもしれないからです。

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

  `notify_all`()
  `notifyAll`()

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

## 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 引数の値を偽にした場合、ブロックしません。引数なしで呼び出した場合にブロックするような状況であった場合には直ちに偽を返します。それ以外の場合には、引数なしで呼び出したときと同じ処理を行い真を返します。

  `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()` メソッドで値を真に、 `clear()` メソッドで値を偽にリセットします。 `wait()` メソッドはフラグがTrueになるまでブロックします。

class `threading.` `Event`

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

  `is_set`()
  `isSet`()

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

    バージョン 2.6 で変更: 新たに `is_set()` 構文が使えるようになりました。

  `set`()

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

  `clear`()

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

  `wait`([timeout])

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

    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は、すでにアクセス可能でなくなった領域にアクセスしようとするためです)

### ナビゲーション

- 索引
- モジュール |
- 次へ |
- 前へ |
- Python 2.7ja1 documentation »
- Python 標準ライブラリ »
- 16. オプションのオペレーティングシステムサービス »