互斥锁是最基本的同步形式,用于保护临界区
#include <pthread.h> int pthread_mutex_lock(pthread_mutex_t *mptr); int pthread_mutex_trylock(pthread_mutex_t *mptr); int pthread_mutex_unlock(pthread_mutex_t *mptr); // return : 0/errno
// 互斥锁静态初始化 pthread_mutex_t mMutex = PTHREAD_MUTEX_INITIALIZER // 动态初始化 pthread_mutex_t *mptr = malloc(sizeof(pthread_mutex_t)); pthread_mutex_init(mptr, 0);
// 通常情况下,我们将互斥锁和需要保护的对象封装一个结构体内 struct { pthread_mutex_t mutex; int shObj; } shared = { PTHREAD_MUTEX_INITIALIZER };
// 线程间共享互斥锁的生产者消费者 #include "unpipc.h" #define MAXNITEMS 1000000 #define MAXNTHREADS 100 int nitems; /* read-only by producer and consumer */ struct { pthread_mutex_t mutex; int buff[MAXNITEMS]; int nput; int nval; } shared = { PTHREAD_MUTEX_INITIALIZER }; void *produce(void *), *consume(void *); int main(int argc, char **argv) { int i, nthreads, count[MAXNTHREADS]; pthread_t tid_produce[MAXNTHREADS], tid_consume; if (argc != 3) err_quit("usage: prodcons2 <#items> <#threads>"); nitems = min(atoi(argv[1]), MAXNITEMS); nthreads = min(atoi(argv[2]), MAXNTHREADS); Set_concurrency(nthreads); /* 4start all the producer threads */ for (i = 0; i < nthreads; i++) { count[i] = 0; Pthread_create(&tid_produce[i], NULL, produce, &count[i]); } /* 4wait for all the producer threads */ for (i = 0; i < nthreads; i++) { Pthread_join(tid_produce[i], NULL); printf("count[%d] = %d\n", i, count[i]); } /* 4start, then wait for the consumer thread */ Pthread_create(&tid_consume, NULL, consume, NULL); Pthread_join(tid_consume, NULL); exit(0); } /* end main */ void * produce(void *arg) { for ( ; ; ) { Pthread_mutex_lock(&shared.mutex); if (shared.nput >= nitems) { Pthread_mutex_unlock(&shared.mutex); return(NULL); /* array is full, we're done */ } shared.buff[shared.nput] = shared.nval; shared.nput++; shared.nval++; Pthread_mutex_unlock(&shared.mutex); *((int *) arg) += 1; } } void * consume(void *arg) { int i; for (i = 0; i < nitems; i++) { if (shared.buff[i] != i) printf("buff[%d] = %d\n", i, shared.buff[i]); } return(NULL); }
互斥锁可以用在进程间共享:互斥锁建在共享内存区,并设置PTHREAD_PROCESS_SHARED属性,这样该互斥锁为系统级别
pthread_mutex_t *mptr //point to the mutex in shm pthread_mutexattr_t mattr; mptr = /* mutex in shm */ Pthread_mutexattr_init(&mattr); Pthread_mutexattr_setpshared(&mattr, PTHEAD_PROCESS_SHARED); Pthread_mutex_init(mptr, &mattr);当在进程间共享一个互斥锁时,持有该互斥锁的进程在持有期间终止,没有办法让系统在进程终止时自动释放所持有的锁,读写锁和Posix信号量亦然;进程终止时内核总是自动清理的唯一同步锁类型是fcntl记录锁。线程在获取锁的情况下被另一个线程Pthread_cancel掉时,我们可以设置清理处理程序pthread_cleanup_pop/push应对该状况。