在多線程編程中,通常都需要線程間的同步,一個線程要等待另一個線程的事件才繼續執行,一般的做法是采用WaitForSingleObject和WaitForMultipleObjects()函數來實現。
但在實際的應用中,經常出現等待線程卡死的狀況,也就是說等待的事件一直無效。為什么事件一直無效呢?很多的情況是等待線程阻塞了另外的線程,使另外的線程無法設置事件有效。為什么會阻塞呢?原因就比較多了,需要具體問題具體分析。
?WaitForSingleObject和WaitForMultipleObjects()都是阻塞函數,事件無效就一直不返回,從而阻塞該線程,使該線程無法處理其他的事務,如果其他的線程發送消息過來,將得不到處理而不返回,從而將其他的線程也阻塞,造成相互等待,這就是臭名昭著的“死鎖”!!!
? 微軟提供了另外一個函數可以解決該問題,它就是MsgWaitForMultipleObjects()函數,該函數不但可以等待事件,還可以等待消息,從而處理消息,使線程不阻塞。該函數的具體解釋前參考MSDN或網絡。
一般的使用方法為:
[cpp] view plaincopy print?
DWORD?dwRet?=?0;????MSG?msg;??DWORD?dwStartTime?=?GetTickCount();???while?(TRUE)??????{????????????????????dwRet?=?GetTickCount()?-?dwStartTime;??if?((GetTickCount()?-?dwStartTime)?>?10000)??{??AfxMessageBox(_T("獲取數據超時,請檢測設備網絡連接!"),?MB_OK?|?MB_ICONERROR);??return?NULL;??}?????????????????????????dwRet?=?MsgWaitForMultipleObjects?(1,?&g_hRetEvent,?FALSE,?100,?QS_ALLINPUT);??????switch(dwRet)????{????case?WAIT_OBJECT_0:???break;???case?WAIT_OBJECT_0?+?1:?????????if?(PeekMessage(&msg,?NULL,?0,?0,?PM_REMOVE))??{??TranslateMessage(&msg);??DispatchMessage(&msg);?????}??continue;???case?WAIT_TIMEOUT:???continue;??default:?????AfxMessageBox(_T("數據獲取失敗,未知錯誤!"),?MB_OK?|?MB_ICONERROR);????return?NULL;??break;???}?????break;??}??
DWORD dwRet = 0;
MSG msg;
DWORD dwStartTime = GetTickCount();
while (TRUE) {
//超時判斷 5sdwRet = GetTickCount() - dwStartTime;
if ((GetTickCount() - dwStartTime) > 10000)
{
AfxMessageBox(_T("獲取數據超時,請檢測設備網絡連接!"), MB_OK | MB_ICONERROR);
return NULL;
}//wait for m_hThread to be over,and wait for
//QS_ALLINPUT(Any message is in the queue) //dwRet = WaitForSingleObject(g_hRetEvent, INFINITE);
dwRet = MsgWaitForMultipleObjects (1, &g_hRetEvent, FALSE, 100, QS_ALLINPUT); switch(dwRet)
{
case WAIT_OBJECT_0: //返回數據達到
break; //break the loop
case WAIT_OBJECT_0 + 1: //界面消息
//get the message from Queue //and dispatch it to specific window
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
continue;
case WAIT_TIMEOUT: //超時
continue;
default: AfxMessageBox(_T("數據獲取失敗,未知錯誤!"), MB_OK | MB_ICONERROR);return NULL;
break; // unexpected failure
} break;
}
特別是在主線程和界面線程中推薦使用該函數,可以避免很多麻煩!!!
總結
以上是生活随笔為你收集整理的用MsgWaitForMultipleObjects代替WaitForSingleObject和WaitForMultipleObjects()的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。