VC MFC中線程同步對象的區別

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章