2010年11月26日 星期五

WaitForSingleObject卻無法跳出!?

這是一個很好的sample code

 

UINT fnThread0(LPVOID p)

{

ThreadPara* pPara = (ThreadPara*)p;

while (pPara->bStart)

{

clock_t c1 = clock();

if ( c1 % 1000 < 250 * 1 )

pPara->pDlg->GetDlgItem(IDC_TEXT1)->SetWindowText("\\");

else if ( c1 % 1000 < 250 * 2 )

pPara->pDlg->GetDlgItem(IDC_TEXT1)->SetWindowText("|");

else if ( c1 % 1000 < 250 * 3 )

pPara->pDlg->GetDlgItem(IDC_TEXT1)->SetWindowText("/");

else 

pPara->pDlg->GetDlgItem(IDC_TEXT1)->SetWindowText("--");

 

Sleep(250);

}

pPara->pDlg->GetDlgItem(IDC_TEXT1)->SetWindowText("Stop");

return 1000;

}

 

void CThreadDlg::OnBnClickedOk()

{

m_ThreadPara.pDlg = this;

if ( m_ThreadPara.bStart == false )

{

// begin thread

m_ThreadPara.bStart = true;

m_pThreadHandle = AfxBeginThread( fnThread0, &m_ThreadPara );

}

else

{

// close thread

m_ThreadPara.bStart = false;

        Sleep(1000);

::WaitForSingleObject( m_pThreadHandle->m_hThread, INFINITE );

}

Sleep(0);

}

這段code哪裡出了問題呢?其實大家會認為我設了flag而且有等這個thread結束就沒問題了, 但是請看下面的圖



所以, 在設定falsg為false之後, 立即進到wait for single object, 而這時worker thread還沒有完成, 所以進到了更新UI的動作, 但main thread(UI thread)已被WaitForSingleObject block住了, 所以此時worker thread也在等main thread, 於是乎兩個互等, 造成的dead lock...

如何避開呢?其實大家如果記得windows API裡還有一個叫做PostMessage的東西, 建一個自己的message type, 然後寫一個function去處理吧, 這樣一來就不會有這個情形發生...

感謝Jame提供的sample code..這是一個非常好的例子...

 

沒有留言: