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]);