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

[MFC]マルチスレッド3

マルチスレッドその3


WaitForSingleObjectで同期処理を行おうとした場合、同期待ちをしようと

しているスレッドがすでに終了していた場合、関数はWAIT_FAILEDの

エラーを返す。


これは、デフォルトのスレッド生成では、スレッドの処理が完了した時点で

自身のオブジェクトを自動で破棄しているためである。


待つべきスレッドのハンドルが、すでに破棄されているため関数は失敗する。


[自動で破棄する形]

AfxBeginThread(ThreadFunc, NULL);


対処するためには、スレッドの起動方法を変更すればよい。


具体的には、スレッド生成したらすぐに処理を開始するのではなく

指示が出るまで待機させ、その待機している間にオブジェクト自動破棄の

フラグを書き換えてやる。


自動破棄のフラグを無効にした後、改めてスレッドを起動させれば

スレッド処理が完了してもオブジェクト自体は残り、同期待ち処理で

エラーが発生することもなくなる。


↓のように実装(スレッド起動時のみ抜粋)


[コード]

CWinThread *pThread =

   AfxBeginThread(ThreadFunc, NULL, 0, 0, CREATE_SUSPENDED);

pThread->m_bAutoDelete = FALSE;

pThread->ResumeThread();


Sleep(2000);


if (::WaitForSingleObject(pThread->m_hThread, INFINITE) == WAIT_FAILED)
{
  printf("wait error\n");
}

delete pThread;


AfxBeginThreadの第5引数にCREATE_SUSPENDEDを渡すことにより、

スレッドはサスペンド(待機)された状態で生成される。


この時点ではスレッド関数の処理は動いていない。


その間にCWinThreadのメンバ変数 m_bAutoDelete をFALSEにする

(デフォルトはTRUE)事により、自動破棄を無効にする。


それから、スレッド起動を再開するためのメンバ関数 ResumeThread()を呼ぶ。


今回はスレッドオブジェクトを自動破棄しないので、明示的にdeleteする

処理も追加してある。



スレッド生成を複数行う場合も同様の考え方で実現できる。

複数のスレッドを待つためにはWaitForMultipleObjects()といった関数も

あるが、基本的に使い方は同じである。