线程同步之互斥量
互斥量可理解成一把锁,不允许多个线程同时访问公共资源,主要用于解决线程同步访问的问题。
Linux下的互斥量
相关编程接口声明如下:
#include <pthread.h>
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
int pthread_mutex_destroy(pthread_mutex_t *mutex);
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
也可以用宏(结构体常量)来初始化互斥锁:pthread_mutex_t mutex = PTHREAD_MUEXT_INITIALIZER。
以下是个例子。
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#define N 5
int tot = 0;
pthread_mutex_t mutex;
void* add(void *arg) {
int i;
for (i = 0; i < 10000; i++) {
pthread_mutex_lock(&mutex);
tot += 1;
pthread_mutex_unlock(&mutex);
}
return NULL;
}
int main() {
int idx;
pthread_t tid[N];
pthread_mutex_init(&mutex, NULL);
for (idx = 0; idx < N; idx++)
pthread_create(&tid[idx], NULL, add, NULL);
for (idx = 0; idx < N; idx++)
pthread_join(tid[idx], NULL);
pthread_mutex_destroy(&mutex);
return 0;
}
Windows下的互斥量
相关编程接口声明如下:
#include <windows.h>
HANDLE CreateMutex(LPSECURITY_ATTRIBUTES lpAttr, BOOL bInitialOwner, LPCSTR lpName);
DWORD WaitForSingleObejct(HANDLE handle, DWORD dwMilliseconds);
DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE *lpHandles, BOOL bWaitAll, DWORD dwMilliseconds);
BOOL ReleaseMutex(HANDLE hMutex);
BOOL CloseHandle(HANDLE hObject);
以下是Windows版本的示例。
#include <stdio.h>
#include <assert.h>
#include <windows.h>
#include <process.h>
#define N 5
#define MAX 9000000
int tot = 0;
HANDLE hMutex;
unsigned WINAPI Add(void *arg) {
int *cnt = (int*)arg;
for (;;) {
WaitForSingleObject(hMutex, INFINITE);
if (tot >= MAX) {
ReleaseMutex(hMutex);
break;
}
*cnt += 1;
tot += 1;
ReleaseMutex(hMutex);
}
return 0;
}
int main() {
HANDLE hThread[N];
int idx, cnt[N] = {0}, sum = 0;
hMutex = CreateMutex(NULL, FALSE, NULL);
for (idx = 0; idx < N; idx++)
hThread[idx] = (HANDLE)_beginthreadex(NULL, 0, Add, &cnt[idx], 0, NULL);
WaitForMultipleObjects(N, hThread, TRUE, INFINITE);
CloseHandle(hMutex);
for (idx = 0; idx < N; idx++) {
printf("thread %d adds %d\n", idx, cnt[idx]);
sum += cnt[idx];
}
assert(sum == MAX);
return 0;
}