[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()といった関数も
あるが、基本的に使い方は同じである。