1、

1 class CMutex::PrivateData 2 { 3 public: 4 HANDLE hEvent; 5 }; 6 7 ////// 8 CMutex::CMutex() 9 { 10 d = new CMutex::PrivateData(); 11 d->hEvent = CreateEvent( 12 NULL, // default security attributes 13 FALSE, //bManualReset 14 TRUE, // signaled 15 NULL); // unnamed object 16 } 17 18 CMutex::~CMutex() 19 { 20 SetEvent(d->hEvent); 21 CloseHandle(d->hEvent); 22 } 23 24 void CMutex::lock() 25 { 26 WaitForSingleObject(d->hEvent, INFINITE); 27 } 28 29 bool CMutex::tryLock(int timeout) 30 { 31 DWORD dwWaitResult = WaitForSingleObject(d->hEvent, timeout); 32 return (dwWaitResult == WAIT_OBJECT_0); 33 } 34 35 36 void CMutex::unlock() 37 { 38 SetEvent(d->hEvent); 39 }
CMutex類。生成一個事件對象,提供等待和開的接口(互斥事件)。
用於WFSOpen、WFSStartUp函數的多次調用控制,windows下采用下面的方法
可以在一個線程的執行函數中創建一個事件對象,然后觀察它的狀態,“有信號”(觸發,開,true),如果是”無信號”(未觸發,關,false)就讓該線程睡眠,這樣該線程占用的CPU時間就比較少
HANDLE CreateEvent(
LPSECURITY_ATTRIBUTES lpEventAttributes, // SD 一般為空
BOOL bManualReset, // reset type 事件是自動復位(false)還是人工復位(true)
BOOL bInitialState, // initial state 初始狀態,有信號(true),無信號(false)
LPCTSTR lpName // object name 事件對象名稱 );
******
代碼中CreateEvent默認初始狀態是true即有信號狀態,當執行waitForSingleObject時不會等待。 並且是自動復位的,在執行waitForSingleObject之后會變成未觸發(無信號)狀態。
******
WaitForSingleObject(d->hEvent, INFINITE);
原型WaitForSingleObject proto hObject:DWORD, dwTimeout:DWORD
//生成事件對象后,通過調用此函數來讓線程進入等待狀態
//hObject 指向同步對象的指針
//等待同步對象變成”有信號“前的等待時間,如果想要線程一直等待,請把該參數設為INFINITE(該值等於0xffffffff)
SetEvent(d->hEvent) //設置為“有信號”
首先CMutex的構造函數中,CreateEvent是默認觸發狀態,並且是自動復位模式。
然后在startup中,調用d->m_bStartUp.tryLock(0)、這個接口會調用WaitForSingleObject, 自動模式下執行Wait之后會將事件改變為未觸發狀態,由於傳入0,本次調用會返回WAIT_OBJECT,這個判斷是true不會進入if執行。
然后第二次調用d->m_bStartUp.tryLock(0),如果之前沒有做setEvent變為觸發,則會返回false。 同理d->m_bStartOrCleaning這個對象用來判斷異步接口調用也是類似原理
因為線程的句柄在線程運行時是未觸發的,線程結束運行,句柄處於觸發狀態。 所以可以用WaitForSingleObject()來等待一個線程結束運行。

1 #include "mutex.h" 2 3 #ifndef Q_OS_WIN 4 5 #include<stdio.h> 6 #include <pthread.h> 7 #include <unistd.h> 8 9 class CMutex::PrivateData 10 { 11 public: 12 pthread_mutex_t mutex; 13 bool bInitialized; 14 }; 15 16 ////// 17 CMutex::CMutex() 18 { 19 d = new CMutex::PrivateData(); 20 d->bInitialized = (pthread_mutex_init(&d->mutex, NULL) == 0); 21 } 22 23 CMutex::~CMutex() 24 { 25 if(d->bInitialized){ 26 pthread_mutex_unlock(&d->mutex); 27 pthread_mutex_destroy(&d->mutex); 28 } 29 } 30 31 void CMutex::lock() 32 { 33 if(!d->bInitialized){ 34 return; 35 } 36 pthread_mutex_lock(&d->mutex); 37 } 38 39 bool CMutex::tryLock(int timeout) 40 { 41 if(!d->bInitialized){ 42 return false; 43 } 44 45 int ret = pthread_mutex_trylock(&d->mutex); 46 if(ret == 0){ 47 return true; 48 } 49 50 while(timeout > 0){ 51 --timeout; 52 usleep(1000); 53 ret = pthread_mutex_trylock(&d->mutex); 54 if(ret == 0){ 55 return true; 56 } 57 } 58 return false; 59 } 60 61 void CMutex::unlock() 62 { 63 if(!d->bInitialized){ 64 return; 65 } 66 pthread_mutex_unlock(&d->mutex); 67 } 68 69 70 #endif //Q_OS_UNIX
linux環境中采用下面方法 pthread_mutex_init(//此接口在CMutex構造函數中調用,用於互斥鎖的初始化
pthread_mutex_t *restrict mutex, //互斥鎖
const pthread_mutexattr_t *restrict attr //互斥鎖的屬性,為空則使用默認屬性 )
初始化成功執行后,互斥鎖被初始化為未鎖狀態;
初始化成功bInitialized = true; pthread_mutex_trylock(&mymutex) 此接口會嘗試鎖定mymutex,如果該互斥鎖已經鎖定則返回一個非0的錯誤碼; 如果該互斥鎖沒有鎖定則返回0,表示鎖定成功。 當第一次調用trylock(0)之后,返回的是true;若不進行unlock,則之后調用trylock(0)都會返回false。 用來管理判斷StartUp是否執行,以及open函數是否執行