[MFC]マルチスレッド2 | Assertion Failed!

[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失敗する。


この現象の原因と対処はまた次回。