● 范圍:線程鎖和進(jìn)程鎖,前者僅用于同一進(jìn)程內(nèi)多線程間,而后者用于進(jìn)程間,顯然,它也能用于同一進(jìn)程內(nèi)多線程間,但效率較低。posix的互斥體既可以是線程鎖,也可以是進(jìn)程鎖,這由它的一個(gè)屬性決定:pthread_process_shared或pthread_process_private。win32中的臨界區(qū)是一種線程鎖,而互斥體既可以是線程鎖,也可以是進(jìn)程鎖,這由它的一個(gè)名稱決定:createmutex中的第3個(gè)參數(shù)。
● 類型:posix中的互斥體,包括普通鎖、遞歸鎖、檢測(cè)鎖和適應(yīng)鎖四種;而win32中的臨界區(qū)在同一線程內(nèi)可多次加鎖和解鎖,相當(dāng)于遞歸鎖,而互斥體則相當(dāng)于普通鎖。
● 操作:包括創(chuàng)建鎖、加鎖、解鎖、檢測(cè)鎖和銷毀鎖5種操作,其中加鎖操作又可分為永久等待和超時(shí)等待2種。對(duì)于win32中的臨界區(qū),不存在超時(shí)等待的加鎖。
接口
所有鎖操作,成功返回0,失敗posix返回非0的錯(cuò)誤碼,win32返回-1,調(diào)用getlasterror可獲取錯(cuò)誤碼。對(duì)于超時(shí)加鎖,第2個(gè)參數(shù)超時(shí)不是時(shí)間差,而是絕對(duì)到期時(shí)間。對(duì)于win32中的互斥體,廢棄返回1,超時(shí)返回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);
#ifdef _POSIX_THREAD2
#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_WINNT11
# define _WIN32_WINNT 0x050112
#endif13
#include <winsock2.h>14

15
typedef struct 16
{17
int type_;18
union19
{20
HANDLE proc_lock_;21
CRITICAL_SECTION thr_lock_;22
};23
}mutex_t;24
typedef void mutexattr_t;25

26
#else27
#error Currently only support win32 and posix thread models28
#endif29

30
#define MUTEX_THREAD_SHARED 131
#define MUTEX_PROCESS_SHARED 232

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);實(shí)現(xiàn)
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
}
int mutex_init(mutex_t* m,int scope,int type,const char* name,mutexattr_t* attr,SECURITY_ATTRIBUTES* sa)2
{3
#ifdef _POSIX_THREAD4
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_SHARED15
ret = pthread_mutexattr_setpshared(attr,lock_scope);16
#endif17
}18
if(0==ret && 0 != type)19
{20
#ifdef __USE_UNIX9821
ret = pthread_mutexattr_settype(attr,lock_type);22
#endif23
}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
#else30
m->type_ = scope;31
switch (m->type_)32
{33
case MUTEX_THREAD_SHARED:34
__try35
{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
#endif55
}56

57
int mutex_lock(mutex_t* m)58
{59
#ifdef _POSIX_THREAD60
return pthread_mutex_lock(m);61
#else62
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
#endif80
}81

82
int mutex_timedlock(mutex_t* m,const struct timeval* val)83
{84
//val should be an absolute time.85
#ifdef _POSIX_THREAD86
struct timespec ts = {.tv_sec = val->tv_sec,.tv_nsec=val->tv_usec*1000};87
return pthread_mutex_timedlock(m,&ts);88
#else89
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
#endif117
}118

119
int mutex_trylock(mutex_t* m)120
{121
#ifdef _POSIX_THREAD122
return pthread_mutex_trylock(m);123
#else124
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
#endif144
}145

146
int mutex_unlock(mutex_t* m)147
{148
#ifdef _POSIX_THREAD149
return pthread_mutex_unlock(m);150
#else151
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
#endif165
}166

167
int mutex_destroy(mutex_t* m)168
{169
#ifdef _POSIX_THREAD170
return pthread_mutex_destroy(m);171
#else172
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
#endif186
}



