スレッドオブジェクトの終了を待つ

今回もスレッドの話が続きます。一応スレッドの作成方法はわかっているのですから、
スレッドを安全に終了させたくなるのが人情というものです(?)
副スレッドが終了した状態でプロセスを終了したいですね。

・WaitForSingleObject

これは、正確にはさまざまなオブジェクトの状態を得ることが出来る関数です。
スレッドもこの関数で状態を取得出来るオブジェクトなので、この関数を使ってみます。
では2種類の副スレッドfncThread1・fncThread2 を作成し、
それぞれ数値を足していくプログラムを作ってみましょう。
fncThread2は前回と同じなので割愛します。

//==============================
//  スレッドファンクション1
DWORD WINAPI fncThread1 (LPVOID lpVparam) {

     WCHAR wcStr[64];
     int i=0;
     RECT Rect1={10,30,200,48};

     while (i<5000)
          {
          i+=2;
          wsprintf(wcStr, _T("Thread1= %5d"),i);	
          DrawText(g_hdc, wcStr, -1, &Rect1, DT_LEFT);
     } //while

     // hThread2のスレッドオブジェクト終了まで待つ
     WaitForSingleObject(hThread2,INFINITE);

     wsprintf(wcStr, _T("Thread1=   END"));	
     DrawText(g_hdc, wcStr, -1, &Rect1, DT_LEFT);

     return 0;
}

fncThread2 関数では1づつインクリメントするのに対して、
fncThread1 関数内では+2づつ足していきます、
優先順位は同じですから、当然こちらのほうが早くwhileループを抜けますね。
抜けた後ですが、WaitForSingleObject 関数によってfncThread2 が終了するまで待ちます。
シグナル状態 fncThread1 関数は標準よりも高めに、fncThread2 関数は低めに設定します。
それぞれの関数内での処理はインクリメントだけなので割愛します。

では以上を踏まえたソースを実行してみましょう。

シグナル状態になるまで待つ

Thread1(上)がまず「5000」になりますが、WaitForSingleObject でThread2(下)が終了するまで待ちます。
Thread2は「5000」になると「END」を表示し、スレッドを抜けます。
するとThread2がシグナル状態になるので、Thread1の処理が返されこちらも「END」と表示します。

DWORD WaitForSingleObject( HANDLE hHandle, DWORD dwMilliseconds );
・指定されたオブジェクトがシグナル状態になる、もしくはタイムアウト時間が経過すると制御を返します
第一引数 hHandle には、オブジェクトのハンドルを指定します
第二引数 dwMilliseconds には、タイムアウト時間をミリ秒(ms)単位で指定します
dwMillisecondsのパラメータ
 0・・・・・・・・・・・指定されたオブジェクトの状態を調べ、即座に制御を返します
 1~・・・・・・・・・指定された時間を過ぎると、オブジェクトが非シグナル状態でも制御を返します
 INFINITE・・・・ オブジェクトがシグナル状態になるまで待機し続けます

戻り値 成功なら関数が制御を返した原因(以下の3種類)が、失敗ならWAIT_FAILED が返ります。
 ・WAIT_ABANDONED・・・放棄されていたミューテックスの所有権を得た
 ・WAIT_OBJECT_0・・・指定したオブジェクトがシグナル状態になった
 ・WAIT_TIMEOUT・・・・タイムアウト時間が経過しオブジェクトは非シグナル状態であった

ソースの表示

2005/7/9


戻る