对多线程死锁的浅析
對于線程同步問題,有了進一步的理解:詳見我寫的關于多線程同步的文章(已作修改):http://blog.csdn.net/yjgx007/archive/2004/09/04/94559.aspx,主線程A等待另一個線程B的完成才能繼續,在線程B中又要更新主線程A的界面,這里涉及了同步問題以及由此可能產生的死鎖問題,同步問題在修改后的文章中講得比較清楚了,對于線程之間可能產生死鎖的淺析如下:
在等待線程B中更新主線程A的界面,如果未能正確處理A,B兩線程同步的問題,極有可能導致兩線程間的死鎖,看下面代碼:
?UINT CMsiTestDlg::UpdateDeviceContent(LPVOID pParam)
{
?CMsiTestDlg* pDlg = (CMsiTestDlg*)pParam;
?int i = 0;
?do {
??pDlg->m_progress.SetPos(i);?// 更新線程A中的進度條
??Sleep(500);
?} while(i++<10);
?return 0;
}
void CMsiTestDlg::OnButton1()
{
?MSG msg;
?CWinThread* m_pUpdateThread = AfxBeginThread(UpdateDeviceContent, (LPVOID)this/*, THREAD_PRIORITY_BELOW_NORMAL*/);
?if (m_pUpdateThread)
?{
while (::WaitForSingleObject(m_pUpdateThread->m_hThread, INFINITE) != WAIT_OBJECT_0)?//開始等待線程B至結束(線程結束時將返回WAIT_OBJECT_0)
???PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE); //獲取當前線程消息(可能是A線程也可能是B線程)并將消息從消息隊列中移除
?? DispatchMessage(&msg); // 重新分發消息
...
?}
?MessageBox("Thread is end!");
}
m_pUpdateThread->m_hThread 是等待線程B,這樣調用似乎沒有什么問題,在VC++中跟蹤到線程B的線程函數UpdateDeviceContent中的 pDlg->m_progress.SetPos(i);?時,發現程序不能繼續執行,表現為在線程B中對主線程A的界面更新發生了阻塞(這里暫不 考慮界面線程,權當由主線程處理),為何?原因就在于 WaitForSingleObject(m_pUpdateThread->m_hThread, INFINITE)最后一個參數INFINITE - 無限期等待線程B的結束返回,從而產生了不幸:
線程A對線程B無限期等待造成未能重新分發消息(包括界面重繪WM_PAINT, 定時WM_TIMER以及硬件輸入和系統消息,就里特指WM_PAINT消息),造成線程B的阻塞,線程B的阻塞又造成線程A的進一步等待造成線程A的阻塞,這就導致了死鎖。
解決方法是:設置WaitForSingleObject的等待時間為一定值,如500毫秒,這樣,線程A如若等不到線程B的結束,也會返回,并分發消息,使得線程B的執行得以正常繼續,從而也就保證了線程A和線程B之間的正常同步!
轉載于:https://www.cnblogs.com/pcdelphi/archive/2009/04/18/2018039.html
總結
- 上一篇: 工厂模式与策略模式
- 下一篇: 让ModalPopupExtender的