互斥锁,用来保证任一时刻只有单个线程或进程拥有对共享资源的互斥访问权,在这里将posix thread中的互斥体、win32中的互斥体和临界区,统称为互斥锁,其特点如下: ● 范围:线程锁和进程锁,前者仅用于同一进程内多线程间,而后者用于进程间,显然,它也能用于同一进程内多线程间,但效率较低。posix的互斥体既可以是线程锁,也可以是进程锁,这由它的一个属性决定:pthread_process_shared或pthread_process_private。win32中的临界区是一种线程锁,而互斥体既可以是线程锁,也可以是进程锁,这由它的一个名称决定:createmutex中的第3个参数。 ● 类型:posix中的互斥体,包括普通锁、递归锁、检测锁和适应锁四种;而win32中的临界区在同一线程内可多次加锁和解锁,相当于递归锁,而互斥体则相当于普通锁。 ● 操作:包括创建锁、加锁、解锁、检测锁和销毁锁5种操作,其中加锁操作又可分为永久等待和超时等待2种。对于win32中的临界区,不存在超时等待的加锁。
接口
所有锁操作,成功返回0,失败posix返回非0的错误码,win32返回-1,调用getlasterror可获取错误码。对于超时加锁,第2个参数超时不是时间差,而是绝对到期时间。对于win32中的互斥体,废弃返回1,超时返回2。
1
#ifdef _POSIX_THREAD
2
#include <pthread.h>
3
#include <sys/time.h>
4
5
typedef pthread_mutex_t mutex_t;
6
typedef pthread_mutexattr_t mutexattr_t;
7
typedef void SECURITY_ATTRIBUTES;
8
9
#elif defined(_WIN32_THREAD)
10
#ifndef _WIN32_WINNT
11
# define _WIN32_WINNT 0x0501
12
#endif
13
#include <winsock2.h>
14
15
typedef struct
16

{
17
int type_;
18
union
19
{
20
HANDLE proc_lock_;
21
CRITICAL_SECTION thr_lock_;
22
};
23
}mutex_t;
24
typedef void mutexattr_t;
25
26
#else
27
#error Currently only support win32 and posix thread models
28
#endif
29
30
#define MUTEX_THREAD_SHARED 1
31
#define MUTEX_PROCESS_SHARED 2
32
33
int mutex_init(mutex_t* m,int scope,int type,const char* name,
34
mutexattr_t* attr,SECURITY_ATTRIBUTES* sa);
35
36
int mutex_lock(mutex_t* m);
37
38
int mutex_timedlock(mutex_t* m,const struct timeval* val);
39
40
int mutex_trylock(mutex_t* m);
41
42
int mutex_unlock(mutex_t* m);
43
44
int mutex_destroy(mutex_t* m); 实现
1
int mutex_init(mutex_t* m,int scope,int type,const char* name,mutexattr_t* attr,SECURITY_ATTRIBUTES* sa)
2

{
3
#ifdef _POSIX_THREAD
4
int ret, init = 0;
5
pthread_mutexattr_t tmp;
6
if(0==attr) attr = &tmp;
7
if(attr==&tmp)
8
{
9
ret = pthread_mutexattr_init(attr);
10
if (0==ret) init = 1;
11
}
12
if(0==ret && 0 != scope)
13
{
14
#ifdef _POSIX_THREAD_PROCESS_SHARED
15
ret = pthread_mutexattr_setpshared(attr,lock_scope);
16
#endif
17
}
18
if(0==ret && 0 != type)
19
{
20
#ifdef __USE_UNIX98
21
ret = pthread_mutexattr_settype(attr,lock_type);
22
#endif
23
}
24
if (0==ret)
25
ret = pthread_mutex_init(m,attr);
26
if (1==init && attr==&tmp)
27
pthread_mutexattr_destroy(attr);
28
return ret;
29
#else
30
m->type_ = scope;
31
switch (m->type_)
32
{
33
case MUTEX_THREAD_SHARED:
34
__try
35
{
36
InitializeCriticalSection(&m->thr_lock_);
37
}
38
__except(EXCEPTION_EXECUTE_HANDLER)
39
{
40
return -1;
41
}
42
return 0;
43
44
case MUTEX_PROCESS_SHARED:
45
m->proc_lock_ = CreateMutexA(sa,FALSE,name);
46
if (0==m->proc_lock_&&ERROR_ACCESS_DENIED==GetLastError())
47
m->proc_lock_ = OpenMutexA(MUTEX_ALL_ACCESS,FALSE,name);
48
if (0==m->proc_lock_)
49
return -1;
50
return 0;
51
52
default: return -1;
53
}
54
#endif
55
}
56
57
int mutex_lock(mutex_t* m)
58

{
59
#ifdef _POSIX_THREAD
60
return pthread_mutex_lock(m);
61
#else
62
switch(m->type_)
63
{
64
case MUTEX_THREAD_SHARED:
65
EnterCriticalSection(&m->thr_lock_);
66
return 0;
67
68
case MUTEX_PROCESS_SHARED:
69
switch (WaitForSingleObject (m->proc_lock_, INFINITE))
70
{
71
case WAIT_OBJECT_0: return 0;
72
case WAIT_ABANDONED: return 1;
73
default: return -1;
74
}
75
break;
76
77
default: return -1;
78
}
79
#endif
80
}
81
82
int mutex_timedlock(mutex_t* m,const struct timeval* val)
83

{
84
//val should be an absolute time.
85
#ifdef _POSIX_THREAD
86
struct timespec ts =
{.tv_sec = val->tv_sec,.tv_nsec=val->tv_usec*1000};
87
return pthread_mutex_timedlock(m,&ts);
88
#else
89
switch(m->type_)
90
{
91
// not support CriticalSection,so simply return -1.
92
case MUTEX_THREAD_SHARED:
93
return -1;
94
95
case MUTEX_PROCESS_SHARED:
96
{
97
FILETIME ft;
98
struct timeval cur,diff;
99
100
GetSystemTimeAsFileTime(&ft);
101
cur = FileTime2TimeVal(&ft);
102
diff = timeval_sub(val,&cur);
103
104
switch (WaitForSingleObject (m->proc_lock_, timeval_millsec(&diff)))
105
{
106
case WAIT_OBJECT_0: return 0;
107
case WAIT_ABANDONED: return 1;
108
case WAIT_TIMEOUT: return 2;
109
default: return -1;
110
}
111
}
112
break;
113
114
default: return -1;
115
}
116
#endif
117
}
118
119
int mutex_trylock(mutex_t* m)
120

{
121
#ifdef _POSIX_THREAD
122
return pthread_mutex_trylock(m);
123
#else
124
switch(m->type_)
125
{
126
case MUTEX_THREAD_SHARED:
127
if (!TryEnterCriticalSection(&m->thr_lock_))
128
return -1;
129
return 0;
130
131
case MUTEX_PROCESS_SHARED:
132
switch (WaitForSingleObject (m->proc_lock_, 0))
133
{
134
case WAIT_OBJECT_0: return 0;
135
case WAIT_ABANDONED: return 1;
136
case WAIT_TIMEOUT: return 2;
137
default: return -1;
138
}
139
break;
140
141
default: return -1;
142
}
143
#endif
144
}
145
146
int mutex_unlock(mutex_t* m)
147

{
148
#ifdef _POSIX_THREAD
149
return pthread_mutex_unlock(m);
150
#else
151
switch(m->type_)
152
{
153
case MUTEX_THREAD_SHARED:
154
LeaveCriticalSection(&m->thr_lock_);
155
return 0;
156
157
case MUTEX_PROCESS_SHARED:
158
if (!ReleaseMutex(m->proc_lock_))
159
return -1;
160
return 0;
161
162
default: return -1;
163
}
164
#endif
165
}
166
167
int mutex_destroy(mutex_t* m)
168

{
169
#ifdef _POSIX_THREAD
170
return pthread_mutex_destroy(m);
171
#else
172
switch(m->type_)
173
{
174
case MUTEX_THREAD_SHARED:
175
DeleteCriticalSection(&m->thr_lock_);
176
return 0;
177
178
case MUTEX_PROCESS_SHARED:
179
if (!CloseHandle(m->proc_lock_))
180
return -1;
181
return 0;
182
183
default: return -1;
184
}
185
#endif
186
}
posted on 2012-06-23 00:08
春秋十二月 阅读(3564)
评论(2) 编辑 收藏 引用 所属分类:
C/C++