セマフォ オブジェクト
セマフォ オブジェクト は、0 から指定した最大値までのカウントを保持する同期オブジェクトです。 カウントは、スレッドがセマフォ オブジェクトの待機を完了するたびにデクリメントされ、スレッドがセマフォを解放するたびにインクリメントされます。 カウントが 0 に達すると、セマフォ オブジェクトの状態が通知されるまでスレッドが正常に待機できなくなります。 セマフォの状態は、カウントが 0 より大きい場合はシグナルに設定され、カウントが 0 の場合は非割り当てに設定されます。
セマフォ オブジェクトは、限られた数のユーザーをサポートできる共有リソースを制御する場合に役立ちます。 これは、リソースを共有するスレッドの数を指定された最大数に制限するゲートとして機能します。 たとえば、アプリケーションが作成するウィンドウの数に制限を設定する場合があります。 ウィンドウの上限に等しい最大カウントを持つセマフォを使用し、ウィンドウが作成されるたびにカウントを減らし、ウィンドウが閉じられるたびにインクリメントします。 アプリケーションは、各ウィンドウが作成される前に 待機関数の 1 つを呼び出してセマフォ オブジェクトを指定します。 カウントが 0 (ウィンドウの制限に達したことを示す) の場合、待機関数はウィンドウ作成コードの実行をブロックします。
スレッドは、CreateSemaphore または CreateSemaphoreEx関数使用してセマフォ オブジェクトを作成します。 作成スレッドは、オブジェクトの初期カウントとカウントの最大値を指定します。 初期カウントは、0 より小さくも最大値よりも大きい値でもない必要があります。 作成スレッドでは、セマフォ オブジェクトの名前を指定することもできます。 他のプロセスのスレッドは、openSemaphore 関数の呼び出しで名前を指定することで、既存のセマフォ オブジェクトへのハンドルを開くことができます。 ミューテックス、イベント、セマフォ、タイマー オブジェクトの名前の詳細については、「プロセス間同期 を参照してください。
セマフォで複数のスレッドが待機している場合は、待機中のスレッドが選択されます。 先入れ先出し (FIFO) の順序は想定しないでください。 カーネル モードの APCs などの外部イベントは、待機順序を変更できます。
セマフォの状態がシグナル通知に設定されたため、 待機関数の 1 つが戻るたびに、セマフォの数が 1 ずつ減少します。 ReleaseSemaphore 関数は、セマフォの数を指定した量だけ増やします。 カウントを 0 未満にしたり、最大値より大きくしたりすることはできません。
通常、セマフォの初期カウントは最大値に設定されます。 その後、保護されたリソースが使用されると、そのレベルからカウントが減らされます。 または、初期カウントが 0 のセマフォを作成して、アプリケーションの初期化中に保護されたリソースへのアクセスをブロックすることもできます。 初期化後、ReleaseSemaphore使用して、カウントを最大値にインクリメントできます。
ミューテックス オブジェクトを所有するスレッドは、同じミューテックス オブジェクトの実行がブロックされずにシグナル通知されるまで繰り返し待機できます。 ただし、同じセマフォ オブジェクトを繰り返し待機するスレッドは、待機操作が完了するたびにセマフォのカウントをデクリメントします。カウントがゼロになると、スレッドはブロックされます。 同様に、ミューテックスを所有するスレッドのみが ReleaseMutex 関数を正常に呼び出すことができますが、どのスレッドでも、ReleaseSemaphore を使用してセマフォ オブジェクトの数を増やすことができます。
スレッドは、のいずれかの待機関数の呼び出しで同じセマフォ オブジェクトを繰り返し指定することで、セマフォの数を複数回減らすことができます。 ただし、同じセマフォの複数のハンドルを含む配列で複数オブジェクト待機関数の 1 つを呼び出しても、複数のデクリメントは発生しません。
セマフォ オブジェクトの使用が完了したら、CloseHandle 関数を呼び出してハンドルを閉じます。 セマフォ オブジェクトは、最後のハンドルが閉じられたときに破棄されます。 ハンドルを閉じてもセマフォの数には影響しません。したがって、ハンドルを閉じる前またはプロセスが終了する前に、ReleaseSemaphore を必ず呼び出してください。 それ以外の場合、保留中の待機操作は、タイムアウト値が指定されているかどうかに応じて、タイムアウトするか無期限に続行されます。
関連トピック
-
セマフォ オブジェクトの使用 の