[MFC]マルチスレッド2
マルチスレッドその2
前回 はマルチスレッドでは、スレッド終了前にメイン処理が終了するとメモリリークが
発生するところまで。
で、これを解消するためには、メイン処理が終了する前にスレッド処理が終了するのを
待つ(同期する)必要がある。
// スレッド関数
UINT ThreadFunc(LPVOID param)
{
printf("スレッド起動\n");
Sleep(1000);
printf("スレッド終了\n");
return 0;
}
// メイン処理
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
printf("メイン開始\n");
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
・・・中略
}
else
{
CWinThread *pThread = AfxBeginThread(ThreadFunc, NULL);
if (::WaitForSingleObject(pThread->m_hThread, INFINITE) == WAIT_FAILED)
{
printf("wait error\n");
}
}
printf("メイン終了\n");
return nRetCode;
}
スレッドの終了を同期するために、WaitForSingleObject関数を使う。
コレは、第一引数にスレッドのハンドルを指定し、第二引数にタイムアウト時間を
設定することで、指定時間指定スレッドの終了を待つものである。
第一引数のスレッドハンドルは、スレッド生成時に受け取ったCWinThread
のメンバ変数 m_hThread を指定すればよい。
第二引数にINFINITEを指定すると、タイムアウト時間は無制限つまり
スレッドが終了するまで待ち続けるということになる。
実際に実行した際の結果はこちら。
[結果]
> メイン開始
> スレッド起動
> スレッド終了
> メイン終了
今回はきちんとスレッドの起動と終了がメインの間に入っている。
通常であれば、コンソール画面も一瞬で消えてしまう程度のコードだが、
スレッド関数内の1秒スリープがあるため、コンソールも1秒ちょっと表示される。
また、メモリリークも解消された。
しかし、今度は次のような問題が出てくる。
WaitForSingleObject で待とうとしているスレッド関数が、待ち処理に入る前に
すでに終了していた場合はどうなるだろうか。
例えば、メイン処理のWaitForSingleObjectの直前に 2秒のスリープを
入れてみた場合、結果は以下のようになる。
[結果]
> メイン開始
> スレッド起動
> スレッド終了
> wait error
> メイン終了
上記のように、WaitForSingleObjectに失敗する。
この現象の原因と対処はまた次回。