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