這是一個很好的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..這是一個非常好的例子...
沒有留言:
張貼留言