スレッドの同期

ルーチン WaitForSingleObjectWaitForMultipleObjects により,スレッドは,スレッドの完了や他のスレッドからのシグナルといったさまざまな状況を待つことができます。これらのルーチンにより,スレッドとプロセスは,無限にまたは指定されたタイムアウト期間が経過するまで,CPU リソースをまったく消費せずに効率的に待機することができます。

WaitForSingleObject は,第 1 パラメタとしてオブジェクト・ハンドルを取り,そのハンドルが引用するオブジェクトがシグナル状態になるか,指定されたタイムアウト値が経過するまで返りません。次に構文を示します。

WaitResult = WaitForSingleObject (ObjectHandle, [ Timeout ] )

タイムアウトを使用する場合,その値を第 2 パラメタとしてミリ秒単位で指定します。値 WAIT_INFINITE は無限大のタイムアウトを表し,この場合,関数は ObjectHandle が完了するまで待つことになります。

WaitForMultipleObjects もこれと似ていますが,第 2 パラメタが Windows オブジェクト・ハンドルの配列である点が異なります。第 1 パラメタとしては,待機の対象とするハンドル数を指定します。これは作成されたスレッド総数よりも小さい値でなくてはならず,最大値は 64 です。この関数は,すべてのイベントが完了するまで待つか,いずれか 1 つのオブジェクトが完了した時点で実行を再開することができます。

スレッドが決して使用可能にならないオブジェクトを待っていると,デッドロックが発生します。待機の対象としているスレッドが決して終了しない可能性がある場合,タイムアウト・パラメタを使用してください。リソースの衝突の可能性を発見し,それを避ける方法については,『Microsoft Systems Journal, vol. 8』の「Detecting Deadlocks in Multithreaded Win32 Applications」(Ruediger Asche 著) を参照してください。

スレッドの中断と再開

SuspendThread を使うと,スレッドの実行を停止することができます。SuspendThread は,スレッドの実行が中断されるコード内のポイントを制御するわけではないので,同期の目的にはそれほど有用ではありません。しかし,スレッドの作業を終了させるユーザー入力を確認する必要があるような場合,スレッドを中断させるようにすると便利です。入力が確認されたらスレッドを終了させ,そうでなければ実行を再開させます。

中断状態で作成されたスレッドは,中断されたスレッドへのハンドルを指定して ResumeThread が呼び出されるまでは実行を開始しません。これは,スレッドが実行を開始する前に,その状態を初期化したいときに便利です。スレッドの作成時の中断は,1 回限りの同期に有効です。ResumeThread は,中断されたスレッドが,コードの最初から実行を再開することを保証します。