SignalObjectAndWait 関数 (synchapi.h)
1 つのオブジェクトにシグナルを送信し、別のオブジェクトを 1 つの操作として待機します。
構文
DWORD SignalObjectAndWait(
[in] HANDLE hObjectToSignal,
[in] HANDLE hObjectToWaitOn,
[in] DWORD dwMilliseconds,
[in] BOOL bAlertable
);
パラメーター
[in] hObjectToSignal
シグナルを受け取るオブジェクトへのハンドル。 このオブジェクトには、セマフォ、ミューテックス、またはイベントを指定できます。
ハンドルがセマフォの場合は、 SEMAPHORE_MODIFY_STATE アクセス権が必要です。 ハンドルがイベントの場合は、 EVENT_MODIFY_STATE アクセス権が必要です。 ハンドルがミューテックスであり、呼び出し元がミューテックスを所有していない場合、関数は ERROR_NOT_OWNERで失敗します。
[in] hObjectToWaitOn
待機するオブジェクトへのハンドル。 SYNCHRONIZE アクセス権が必要です。詳細については、「同期オブジェクトのセキュリティとアクセス権」を参照してください。 ハンドルを指定できるオブジェクトの種類の一覧については、「解説」セクションを参照してください。
[in] dwMilliseconds
タイムアウト間隔 (ミリ秒単位)。 関数は、オブジェクトの状態が非署名で、完了または非同期プロシージャ呼び出し (APC) オブジェクトがキューに登録されていない場合でも、間隔が経過した場合に を返します。 dwMilliseconds が 0 の場合、関数はオブジェクトの状態をテストし、キューに登録された完了ルーチンまたは APC をチェックして、直ちにを返します。 dwMilliseconds が INFINITE の場合、関数のタイムアウト間隔は経過しません。
[in] bAlertable
このパラメーターが TRUE の場合、システムが I/O 完了ルーチンまたは APC 関数をキューに入れ、スレッドが関数を呼び出すと、 関数が返されます。 FALSE の場合、関数は戻らず、スレッドは完了ルーチンまたは APC 関数を呼び出しません。
APC をキューに入れた関数呼び出しが完了すると、完了ルーチンがキューに入れられます。 この関数は を返し、完了ルーチンは 、bAlertable が TRUE で、呼び出し元のスレッドが APC をキューに入れたスレッドである場合にのみ呼び出されます。
戻り値
関数が成功した場合、戻り値は、関数が返される原因となったイベントを示します。 次のいずれかの値を指定できます。
リターン コード/値 | Description |
---|---|
|
指定されたオブジェクトは、所有しているスレッドが終了する前にミューテックス オブジェクトを所有していたスレッドによって解放されなかったミューテックス オブジェクトです。 ミューテックス オブジェクトの所有権は呼び出し元のスレッドに付与され、ミューテックスは非署名に設定されます。
ミューテックスが永続的な状態情報を保護していた場合は、一貫性のためにチェックする必要があります。 |
|
待機は、スレッドにキューに登録された 1 つ以上のユーザー モード 非同期プロシージャ呼び出し (APC) によって終了しました。 |
|
指定したオブジェクトの状態が通知されます。 |
|
タイムアウト間隔が経過し、オブジェクトの状態が非割り当てです。 |
|
関数が失敗しました。 詳細なエラー情報を得るには、GetLastError を呼び出します。 |
解説
SignalObjectAndWait 関数は、SetEvent の後に WaitForSingleObject などの個別の関数呼び出しと比較して、1 つのオブジェクトにシグナルを送信し、別のオブジェクトを待機するより効率的な方法を提供します。
SignalObjectAndWait 関数は、次のオブジェクトを待機できます。
- 変更通知
- コンソール入力
- イベント
- メモリ リソース通知
- Mutex
- Process
- Semaphore
- スレッド
- 待機可能タイマー
スレッドは SignalObjectAndWait 関数を使用して、ワーカー スレッドがオブジェクトにシグナルを送信する前に待機状態であることを確認できます。 たとえば、スレッドとワーカー スレッドでは、ハンドルを使用してイベント オブジェクトを使用して作業を同期できます。 スレッドは、次のようなコードを実行します。
dwRet = WaitForSingleObject(hEventWorkerDone, INFINITE);
if( WAIT_OBJECT_0 == dwRet)
SetEvent(hEventMoreWorkToDo);
ワーカー スレッドは、次のようなコードを実行します。
dwRet = SignalObjectAndWait(hEventWorkerDone,
hEventMoreWorkToDo,
INFINITE,
FALSE);
"signal" と "wait" は、アトミック操作として実行される保証はありません。 他のプロセッサで実行されているスレッドは、 SignalObjectAndWait を呼び出すスレッドが 2 番目のオブジェクトで待機を開始する前に、最初のオブジェクトのシグナル状態を観察できます。
複数のスレッド間でこれらの API を使用するとアプリケーションがデッドロックする可能性があるため、Windows 7 で SignalObjectAndWait と PulseEvent を使用する場合は細心の注意を払ってください。 SignalObjectAndWait 呼び出しによって通知されるスレッドは、SignalObjectAndWait 呼び出しの待機オブジェクトを通知するために PulseEvent を呼び出します。 状況によっては、 SignalObjectAndWait の呼び出し元が待機オブジェクトのシグナル状態を時間内に受信できないため、デッドロックが発生します。
直接または間接的にウィンドウを作成する待機関数とコードを使用する場合は注意が必要です。 スレッドがウィンドウを作成する場合は、メッセージを処理する必要があります。 メッセージ ブロードキャストは、システム内のすべてのウィンドウに送信されます。 タイムアウト間隔のない待機関数を使用するスレッドによって、システムがデッドロックする可能性があります。 間接的にウィンドウを作成するコードの例として、DDE と COM CoInitialize の 2 つがあります。 したがって、ウィンドウを作成するスレッドがある場合は、必ず別のスレッドから SignalObjectAndWait を呼び出してください。 これが不可能な場合は、 MsgWaitForMultipleObjects または MsgWaitForMultipleObjectsEx を使用できますが、機能は同等ではありません。
この関数を使用するアプリケーションをコンパイルするには、 0x0400 以降として_WIN32_WINNTを定義します。 詳細については、「 Windows ヘッダーの使用」を参照してください。
要件
要件 | 値 |
---|---|
サポートされている最小のクライアント | Windows XP [デスクトップ アプリ | UWP アプリ] |
サポートされている最小のサーバー | Windows Server 2003 [デスクトップ アプリのみ | UWP アプリ] |
対象プラットフォーム | Windows |
ヘッダー | synchapi.h (Windows.h を含む) |
Library | Kernel32.lib |
[DLL] | Kernel32.dll |