在多线程控制中,可以通过互斥锁,实现多个线程对共享资源的单独访问。在同一时刻,只有一个线程能够掌握互斥锁,只有这个线程能够对共享资源进行访问,其他线程被阻塞,直到互斥锁被释放。
如果,互斥锁上锁期间,有多个线程阻塞,那么所有被阻塞的线程会被设置为可执行状态。第一个执行的线程,取得互斥锁的控制权,上锁。其他线程继续阻塞。
一 创建互斥锁
互斥锁可以被静态创建或动态创建。
静态创建:
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
特别说明:在ubuntu14.04中,由于头文件中使用了ifdef条件编译,3种锁中只有默认锁可用。详见头文件pthread.h
#
define PTHREAD_MUTEX_INITIALIZER \
{ { 0, 0, 0, 0, 0, { __PTHREAD_SPINS } } }
# ifdef __USE_GNU //如果不定义use gnu 是没有下面几种锁的
# define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP \
{ { 0, 0, 0, PTHREAD_MUTEX_RECURSIVE_NP, 0, { __PTHREAD_SPINS } } }
# define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP \
{ { 0, 0, 0, PTHREAD_MUTEX_ERRORCHECK_NP, 0, { __PTHREAD_SPINS } } }
# define PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP \
{ { 0, 0, 0, PTHREAD_MUTEX_ADAPTIVE_NP, 0, { __PTHREAD_SPINS } } }
动态创建:
pthread_mutex_init函数动态的创建,函数原型如下:
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t * attr)
如pthread_mutex_init(mutex,NULL),使用默认值属性初始化,此时为快速互斥锁。
二 锁的属性
互斥锁的属性可由函数pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t * attr)来初始化。
互斥锁的类型由一下几个取值:
PTHREAD_MUTEX_TIMED_NP,这是缺省值,也就是普通锁,也叫快速互斥锁。
PTHREAD_MUTEX_RECURSIVE_NP,递归互斥锁,嵌套锁,允许同一个线程对同一个锁成功获得多次,并通过多次unlock解锁。
PTHREAD_MUTEX_ERRORCHECK_NP,检错互斥锁,检错锁,如果同一个线程请求同一个锁,则返回EDEADLK,否则与PTHREAD_MUTEX_TIMED_NP类型动作相同。
函数pthread_mutex_init()中,第二个参数attr是结构体,而上面三个参数为int。因此不可直接将上述3个值带入。
可通过下面两个函数设置、获取attr值。
pthread_mutexattr_settype(pthread_mutexattr_t *attr , int type)
将锁属性type,设置到attr中;
pthread_mutexattr_gettype(pthread_mutexattr_t *attr , int *type)
从attr中取得锁属性,存入指针type中。
互斥锁的使用比较简单,不再详述。