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函数是否执行

 

posted @ 2018-12-11 10:04  蓦然而然  阅读(8495)  评论(0编辑  收藏  举报