VC MFC中線程同步對象的區別
臨界區 CCriticalSection,在用戶模式工作,適用於保護線程間共享資源,一個線程可以多次Lock不會出錯。不支持在多進程之間工作。
互斥量 CMutex,在內核模式工作,除了支持臨界區的功能,還可以爲互斥量命名,以便在多進程中工作。互斥量比臨界區耗資源。
事件 CEvent,在內核模式工作,適用於一個線程等待另一個線程完成某任務。
信號量 CSemaphore,在內核模式工作,適用於允許特定個數的線程執行某任務。
實例:
CwinThread *pThread;
1、使用互斥對象
HANDLE hMutex;
hMutex = CreateMutex(NULL , false, "mutex");
線程函數使用:
WaitForSingleObject(hMutex,INFINITE);
{
}
ReleaseMutex(hMutex);
<2>
CMutex Section;
線程函數中使用
CsingleLock singlelock;
singlelock(&Section);
singlelock.lock();
singlelock.Unlock();
2、使用事件對象
1 > 第一種實用方式:
HANDLE hEvent;
線程函數中使用:
WaitForSingleObject(hEvent,INFINITE);
{
}
SetEvent(hEvent);
hEvent = CreateEvent(NULL,FALSE,TRUE,"event");//自動重置對象,通知狀態
SetEvent(hEvent);//爲通知狀態
ResetEvent(hEvent);//未通知狀態
3、實用臨界區對象
<1>
CRITICAL_SECTION Section;
InitializeCriticalSection(&Section);
線程中實用
EnterCriticalSection(&Section);
{
}
LeaveCriticalSection(&Section);
<2>
CCriticalSection Section;
線程中使用
Section.Lock();
Section.Unlock();
4、線程啓動
pThread = AfxBeginthread(thradfunction,hwnd);
pThread->m_bAutoDelete = FALSe;//線程爲手動刪除
在OnDestory()
{
WaitForSingleObject(pThread->m_hThread,INFINITE);//等待線程的結束
delete pThread;
}
5、線程通訊
1> ::PostMessage((HWND),WM_USERMSG,0,0);
2> CwinThread::PostThradMessage();
使用事件對象
2 >Cevent threadStart,threadEnd;
UINT ThreadFunction(LPVOID pParam)
{
::WaitForSingleObject(threadStart.m_hObject,INFINITE);
Sleep(1000);
::WaitForSingleObject(threadEnd.m_hObject,INFINITE);
::PostMessage(hWnd,WM_USERMSG,0,0);
}
A()
{
threadStart.SetEvent();
pThread = AfxBeginThread(ThreadFunction,hWnd);
pThread->m_bAutoDelete = FALSE;
delete pThread;
}
6、使用信號量,可以同時讓多個線程共訪同一個資源
Csemaphor *semaphore;
semaphore = new Csemaphore(2,2);
線程函數中使用:
Csinglelock singleLock(semahore);
singlelock.Lock();
(二)、項目中使用
1、使用全局的線程調用,(使用信號量 CRITICAL_SECTION g_Send_EMM_Cs;)
在一個文件中如:Scrambler.cpp中
InitializeCriticalSection(&g_Send_EMM_Cs);//需要初始化
//發送CW到ECMG A線程
UINT SendCWToECMGAThread(LPVOID lParam)
{
EnterCriticalSection(&g_Send_EMM_Cs);
{
}
LeaveCriticalSection(&g_Send_EMM_Cs);
}
可以在其他文件中(如Fmain.cpp中調用)
AfxBeginThread(SendCWToECMGAThread, pDoc);
需要在StdAfx.h中聲明
extern UINT SendCWToECMGAThread(LPVOID lParam);
2、使用類內部調用(使用WINAPI)
在MainFrm.h中聲明:
static DWORD WINAPI ConnectServerOutTime(LPVOID lpParameter);//連接服務器線程超時
在MainFrm.cpp中調用
HANDLE hTreadTime;
hTreadTime = CreateThread(NULL,0,CMainFrame::ConnectServerOutTime,NULL,0,NULL);
hMutex = CreateMutex(NULL,TRUE,NULL);//創建互斥
CloseHandle(hTreadTime);
則會執行:
//啓動的線程
DWORD WINAPI CMainFrame::ConnectServerOutTime(LPVOID lpParameter)
{
if( WAIT_TIMEOUT == WaitForSingleObject(hMutex,2000) )超時兩秒
return 0 ;
}
3、使用事件句柄
HANDLE g_hEcmEvent[3];
g_hEcmEvent[0] = CreateEvent(NULL,TRUE,FALSE,NULL);//創建事件
UINT SendCWToECMGAThread(LPVOID lParam)
{
if(WaitForSingleObject(g_hEcmEvent[0], 4000) == WAIT_OBJECT_0)
{
}
}
可以在其他地方:
SetEvent(g_hEcmEvent[0]);
ResetEvent(g_hEcmEvent[0]);