互斥锁,用来保证任一时刻只有单个线程或进程拥有对共享资源的互斥访问权,在这里将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
5typedef pthread_mutex_t mutex_t;
6typedef pthread_mutexattr_t mutexattr_t;
7typedef 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
15typedef struct
16{
17 int type_;
18 union
19 {
20 HANDLE proc_lock_;
21 CRITICAL_SECTION thr_lock_;
22 };
23}mutex_t;
24typedef 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
33int mutex_init(mutex_t* m,int scope,int type,const char* name,
34 mutexattr_t* attr,SECURITY_ATTRIBUTES* sa);
35
36int mutex_lock(mutex_t* m);
37
38int mutex_timedlock(mutex_t* m,const struct timeval* val);
39
40int mutex_trylock(mutex_t* m);
41
42int mutex_unlock(mutex_t* m);
43
44int mutex_destroy(mutex_t* m); 实现
1int 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
57int 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
82int 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
119int 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
146int 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
167int 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
春秋十二月 阅读(3532)
评论(2) 编辑 收藏 引用 所属分类:
C/C++