CreateEvent的使用說明


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

 

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 CMutex


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函數是否執行

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM