互斥鎖,用來保證任一時刻只有單個線程或進程擁有對共享資源的互斥訪問權,在這里將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
春秋十二月 閱讀(3575)
評論(2) 編輯 收藏 引用 所屬分類:
C/C++