### ナビゲーション

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

# 17.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` を返します。

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

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

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

`threading.``Condition`()

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

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

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

`threading.``enumerate`()

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

`threading.``Event`()

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

class `threading.``local`

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

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

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

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

  バージョン 2.4 で追加.

`threading.``Lock`()

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

`threading.``RLock`()

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

`threading.``Semaphore`([value])

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

`threading.``BoundedSemaphore`([value])

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

class `threading.``Thread`

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

class `threading.``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) に実行されます。

## 17.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__()`) を 呼び出しておかなくてはなりません。

`Thread.``start`()

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

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

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

`Thread.``run`()

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

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

`Thread.``join`([timeout])

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

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

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

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

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

`Thread.``getName`()
`Thread.``setNmae`()

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

`Thread.``name`

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

`Thread.``ident`

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

  バージョン 2.6 で追加.

`Thread.``is_alive`()
`Thread.``isAlive`()

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

  大雑把な言い方をすると、スレッドは `start()` メソッドを呼び出し た瞬間から `run()` メソッドが終了するまでの間生存しています。 モジュール関数、 `enumerate()` は、全ての生存中のスレッドのリス トを返します。

`Thread.``isDaemon`()
`Thread.``setDaemon`()

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

`Thread.``daemon`

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

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

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

## 17.2.2. Lock オブジェクト

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

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

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

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

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

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

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

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

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

`Lock.``release`()

  ロックを解放します。

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

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

  戻り値はありません。

## 17.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` が送出されます。

  戻り値はありません。

## 17.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` オブジェクトを生成して使い ます。

`Condition.``acquire`(*args)

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

`Condition.``release`()

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

`Condition.``wait`([timeout])

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

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

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

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

`Condition.``notify`()

  この条件変数を待っているスレッドがあれば、そのスレッドを起こします。 通知を受け取るか、タイムアウトが発生するまで待ちます。 呼び出し手のスレッドがロックを獲得していないときにこのメソッドを呼 び出すと `RuntimeError` が送出されます。

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

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

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

`Condition.``notify_all`()
`Condition.``notifyAll`()

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

## 17.2.5. Semaphore オブジェクト

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

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

class `threading.``Semaphore`([value])

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

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

  セマフォを獲得します。

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

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

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

`Semaphore.``release`()

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

### 17.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()

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

## 17.2.6. Event オブジェクト

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

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

class `threading.``Event`

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

`Event.``is_set`()
`Event.``isSet`()

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

`Event.``set`()

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

`Event.``clear`()

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

`Event.``wait`([timeout])

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

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

## 17.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 つきで実行するようなタイマを生成します。

`Timer.``cancel`()

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

## 17.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"

## 17.2.9. スレッド化されたコード中でのImport

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

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

### ナビゲーション

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