首页 > 代码库 > 线程间的互斥
线程间的互斥
互斥锁是用来保护一段临界区的(每个进程中访问临界资源的那段代码称为临界区),它可以保证在某段时间内只有一个线程在执行一段代码或者访问某个资源。
1. 互斥锁的初始化pthread_mutex_init(2)
int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr);
PTHREAD_MUTEX_TIMED_NP,这是缺省值,也就是普通锁。当一个线程加锁以后,其余请求锁的线程将形成一个等待队列,并在解锁后按优先级获得锁。这种锁策略保证了资源分配的公平性。
PTHREAD_MUTEX_RECURSIVE_NP,嵌套锁,允许同一个线程对同一个锁成功获得多次,并通过多次unlock解锁。如果是不同线程请求,则在加锁线程解锁时重新竞争。
PTHREAD_MUTEX_ERRORCHECK_NP,检错锁,如果同一个线程请求同一个锁,则返回EDEADLK,否则与PTHREAD_MUTEX_TIMED_NP类型动作相同。这样就保证当不允许多次加锁时不会出现最简单情况下的死锁。
PTHREAD_MUTEX_ADAPTIVE_NP,适应锁,动作最简单的锁类型,仅等待解锁后重新竞争。
2. 互斥锁的锁定pthread_mutex_lock(1)
int pthread_mutex_lock(pthread_mutex_t *mutex);
默认的锁是不可重入(重复进入)的,我们下面的例子会展示这一点,而windows API中的CRITICAL_SECTION以及Mutex还有Java中的synchronized这些是可重入的。
下面利用来mutex来完成来同步以及线程间的互斥,但是我觉得还是不要用mutex来同步,再下一篇文章中会介绍一种同步的方法。例子这样做只是为了与windows中的cs做一个对比而已。
3. 互斥锁的预锁定
int pthread_mutex_trylock(pthread_mutex_t *mutex);
4. 互斥锁的解锁
int pthread_mutex_unlock(pthread_mutex_t *mutex);
5. 互斥锁的销毁
int pthread_mutex_destroy(pthread_mutex_t *mutex);
例子:
#include <stdio.h>#include <unistd.h>#include <pthread.h>#define THREADNUM 10pthread_mutex_t g_mutex_param,g_mutex_thread;int g_num;void *mutexFunc(void *args){ int tid = *(int*)args; usleep(50000); pthread_mutex_unlock(&g_mutex_param); pthread_mutex_lock(&g_mutex_thread); ++g_num; printf("the thread id :%d, the global id :%d\n",tid,g_num); pthread_mutex_unlock(&g_mutex_thread);}int main(){ pthread_t threads[THREADNUM]; pthread_mutex_init(&g_mutex_param,NULL); pthread_mutex_init(&g_mutex_thread,NULL); int i = 0; while(i < THREADNUM) { if(0!=pthread_mutex_lock(&g_mutex_param)) printf("lock fail\n"); printf("main:%d\n",i); pthread_create(&threads[i],NULL,mutexFunc,&i); ++i; } int j = 0; while(j < THREADNUM) { pthread_join(threads[j],NULL); ++j; } pthread_mutex_destroy(&g_mutex_param); pthread_mutex_destroy(&g_mutex_thread); return 0;}
线程间的互斥