在多線程編程中,通常都需要線程間的同步,一個線程要等待另一個線程的事件才繼續(xù)執(zhí)行,一般的做法是采用WaitForSingleObject和WaitForMultipleObjects()函數(shù)來實現(xiàn)。
但在實際的應(yīng)用中,經(jīng)常出現(xiàn)等待線程卡死的狀況,也就是說等待的事件一直無效。為什么事件一直無效呢?很多的情況是等待線程阻塞了另外的線程,使另外的線程無法設(shè)置事件有效。為什么會阻塞呢?原因就比較多了,需要具體問題具體分析。
WaitForSingleObject和WaitForMultipleObjects()都是阻塞函數(shù),事件無效就一直不返回,從而阻塞該線程,使該線程無法處理其他的事務(wù),如果其他的線程發(fā)送消息過來,將得不到處理而不返回,從而將其他的線程也阻塞,造成相互等待,這就是臭名昭著的“死鎖”?。?!
微軟提供了另外一個函數(shù)可以解決該問題,它就是MsgWaitForMultipleObjects()函數(shù),該函數(shù)不但可以等待事件,還可以等待消息,從而處理消息,使線程不阻塞。該函數(shù)的具體解釋前參考MSDN或網(wǎng)絡(luò)。
一般的使用方法為:
- DWORD dwRet = 0;
- MSG msg;
- DWORD dwStartTime = GetTickCount();
- while (TRUE)
- {
- //超時判斷 5s
- dwRet = GetTickCount() - dwStartTime;
- if ((GetTickCount() - dwStartTime) > 10000)
- {
- AfxMessageBox(_T("獲取數(shù)據(jù)超時,請檢測設(shè)備網(wǎng)絡(luò)連接!"), 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: //返回數(shù)據(jù)達到
- 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("數(shù)據(jù)獲取失敗,未知錯誤!"), MB_OK | MB_ICONERROR);
- return NULL;
- break; // unexpected failure
- }
- break;
- }
特別是在主線程和界面線程中推薦使用該函數(shù),可以避免很多麻煩!?。?/p>
|