セマフォ
更新 : 2007 年 11 月
Semaphore クラスは、名前付き (システム全体) またはローカルのセマフォを表します。Windows セマフォはカウント セマフォで、リソースのプールへのアクセス制御に使用できます。
制限されたリソースの管理
スレッドは、WaitHandle クラスから継承した WaitOne メソッドを呼び出して、セマフォに入ります。呼び出しが返されると、セマフォのカウントはデクリメントされます。スレッドがエントリを要求し、カウントがゼロの場合、スレッドはブロックされます。スレッドは Release メソッドを呼び出してセマフォを解放するので、ブロックされたスレッドは入ることができます。ブロックされたスレッドがセマフォに入るための、保障されている順序 (FIFO や LIFO など) はありません。
スレッドは、WaitOne メソッドを繰り返し呼び出すと、複数回セマフォに入ることができます。セマフォを解放するには、スレッドは、Release() メソッドのオーバーロードを同じ回数だけ呼び出すか、Release(Int32) メソッドのオーバーロードを呼び出して、解放するエントリの番号を指定します。
セマフォおよびスレッド ID
Semaphore クラスは、WaitOne および Release メソッドへの呼び出しで、スレッド ID を適用しません。たとえば、セマフォのシナリオの一般的な使い方として、作成側のスレッドと消費側のスレッドがあります。一方のスレッドは常にセマフォのカウントをインクリメントし、もう一方は常にデクリメントします。
プログラマは、スレッドによるセマフォの解放回数が多くなりすぎないように注意する必要があります。たとえば、セマフォのカウントの最大値が 2 で、スレッド A とスレッド B の両方がセマフォに入ったとします。スレッド B でプログラミング エラーが発生し、Release を 2 回呼び出した場合は、どちらの呼び出しも成功します。セマフォのカウントはいっぱいなので、スレッド A が Release を呼び出すと、SemaphoreFullException がスローされます。
名前付きのセマフォ
Windows オペレーティング システムでは、セマフォに名前を付けることができます。名前付きのセマフォはシステム全体で使用されます。つまり、いったん名前付きのセマフォを作成すると、すべてのプロセスのすべてのスレッドがそれを参照できます。したがって、名前付きのセマフォを使用して、スレッドだけでなくプロセスのアクティビティも同期できます。
名前付きのシステム セマフォを表す Semaphore オブジェクトを作成するには、名前を指定するいずれかのコンストラクタを使用します。
メモ : |
---|
名前付きのセマフォはシステム全体で使用されるため、複数の Semaphore オブジェクトで同じ名前付きセマフォを表すことができます。コンストラクタまたは OpenExisting メソッドを呼び出すたびに、新しい Semaphore オブジェクトが作成されます。同じ名前を繰り返し指定すると、同じ名前付きセマフォを表す複数のオブジェクトを作成できます。 |
名前付きのセマフォを使用する際には注意が必要です。それらはシステム全体で使用されるので、別のプロセスが同じ名前を使用すると、予期せずにセマフォに入る場合があります。悪意のあるコードが同じコンピュータで実行されると、サービス拒否攻撃の基本としてこれが使用される場合があります。
アクセス制御セキュリティを使用して、名前付きのセマフォを表す Semaphore オブジェクトを保護します。できれば SemaphoreSecurity オブジェクトを指定するコンストラクタを使用します。また、SetAccessControl メソッドを使用してアクセス制御セキュリティを適用できます。ただし、こうすると、セマフォが作成されてから保護されるまでの間に、脆弱性が生じます。アクセス制御セキュリティでセマフォを保護すると、悪意のある攻撃を防ぐのに役立ちますが、予期しない名前の衝突の問題解決にはなりません。