次の方法で共有


複数のスレッドの実行の同期

競合状態やデッドロックを回避するには、複数のスレッドによるアクセスを共有リソースに同期する必要があります。 相互依存コードが適切な順序で実行されるようにするには、同期も必要です。

ハンドルを使用して複数のスレッドを同期できるオブジェクトが多数あります。 これらのオブジェクトは次のとおりです。

  • コンソール入力バッファー
  • イベント
  • ミューテックス
  • プロセス
  • セマフォ
  • スレッド
  • タイマー

これらの各オブジェクトの状態は、シグナル状態か未シグナル状態です。 待機関数の 1 つの呼び出しでこれらのオブジェクトへのハンドルを指定すると、指定したオブジェクトの状態が通知されるまで呼び出し元のスレッドの実行がブロックされます。

これらのオブジェクトの一部は、何らかのイベントが発生するまでスレッドをブロックする場合に役立ちます。 たとえば、キーストロークやマウス ボタンのクリックなど、未読の入力がある場合、コンソール入力バッファー ハンドルが通知されます。 プロセスまたはスレッドが終了すると、プロセスハンドルとスレッドハンドルにシグナルが送られます。 これにより、たとえば、プロセスで子プロセスを作成し、新しいプロセスが終了するまで独自の実行をブロックできます。

他のオブジェクトは、共有リソースを同時アクセスから保護する場合に役立ちます。 たとえば、複数のスレッドがそれぞれミューテックス オブジェクトへのハンドルを持つことができます。 共有リソースにアクセスする前に、スレッドはミューテックスの状態が通知されるのを待つために、待機関数のいずれかを 呼び出す必要があります。 ミューテックスがシグナル状態になると、リソースにアクセスするために待機中のスレッドが 1 つだけ解放されます。 ミューテックスの状態はすぐに通知されない状態にリセットされるため、他の待機中のスレッドはブロックされたままです。 スレッドがリソースで終了したら、他のスレッドがリソースにアクセスできるようにミューテックスの状態を signaled に設定する必要があります。

1 つのプロセスのスレッドの場合、クリティカル セクション オブジェクトはミューテックスよりも効率的な同期手段を提供します。 クリティカル セクションはミューテックスのように使用され、保護されたリソースを一度に 1 つのスレッドで使用できます。 スレッドは、EnterCriticalSection 関数を使用して、クリティカル セクションの所有権を要求できます。 既に別のスレッドが所有している場合、要求スレッドはブロックされます。 スレッドは、TryEnterCriticalSection 関数を使用して、クリティカル セクションの取得に失敗したときにブロックすることなく、クリティカル セクションの所有権を要求できます。 所有権を受け取ると、スレッドは保護されたリソースを自由に使用できます。 プロセスの他のスレッドの実行は、同じクリティカル セクションに入ろうとしない限り影響を受けません。

WaitForInputIdle 関数は、指定されたプロセスが初期化され、ユーザー入力を待ち、入力が保留中でない状態になるまでスレッドを待たせます。 WaitForInputIdle 呼び出すと、親プロセスと子プロセスの同期に役立ちます。これは、CreateProcessが子プロセスの初期化を完了するのを待たずに戻るためです。

詳細については、「同期」を参照してください。