linux线程同步之互斥锁mutex

本文大部分内容是翻译的官方手册

互斥锁的意义和使用方法较为简单,有点类似于原子操作。

先把常用的几个线程互斥锁相关的api列出,再一个个详细介绍:

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
int pthread_mutex_destroy(pthread_mutex_t *mutex);
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
int pthread_mutexattr_gettype(const pthread_mutexattr_t *restrict attr, int *restrict type);
int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type);


1、pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

功能:用默认参数静态初始化一个互斥量,互斥锁变量本身是一个结构体,这个宏PTHREAD_MUTEX_INITIALIZER是结构体成员的初值。

这个赋值语句等价于:pthread_mutex_init(&mutex,NULL ),区别在于,赋值语句不执行错误检查。

2、int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);

题外知识:restrict 关键字是C99标准提出的,大体作用是告诉编译器,指针mutex是访问变量(*mutex)的唯一方式,这样可以让编译器产生优化的、更高效汇编代码。
形参:@mutex 互斥锁的地址;

@ attr,要给互斥锁赋予什么属性。NULL是指采用默认属性。如果要采用其他属性,应当通过pthread_mutexattr_settype函数来把attr实参结构体填充好。

返回值:成功返回0,失败则直接返回错误号,而不是通过errno返回

注意:已初始化过的互斥锁,不允许再次初始化!否则会出现不可预知的问题。除非该互斥锁被pthread_mutex_destroy( )过。

3、int pthread_mutex_destroy(pthread_mutex_t *mutex);
功能:销毁一个互斥锁,其本质是:使一个互斥锁变量,变为未初始化的状态。

返回值:成功返回0,失败则直接返回错误号,而不是通过errno返回

4、int pthread_mutex_lock(pthread_mutex_t *mutex);

功能:
① 锁定一个互斥锁,并把本线程设为该锁的主人。如果早就被别的线程给锁住了,那么本线程将堵塞,直到该锁被解开位置。

② 如果互斥锁类型为PTHREAD_MUTEX_NORMAL,那么本函数将不进行死锁检测。也即,如果某个线程尝试二次锁定一个未解锁的互斥锁,将会导致死锁。如果某线程试图解锁一个:不是本线程锁住的互斥锁、或未锁定的互斥锁,会导致未定义的行为。
③ 如果互斥锁类型为PTHREAD_MUTEX_ERRORCHECK,那么本函数会检测死锁。也即:如果某个线程尝试二次锁定一个未解锁的互斥锁,则本函数会立即返回错误。如果某线程试图解锁一个:不是本线程锁住的互斥锁、或未锁定的互斥锁,则返回错误。
④ 如果互斥锁类型为PTHREAD_MUTEX_RECURSIVE,则互斥锁会对加锁、解锁次数进行记录。当线程第一次成功获取互斥锁时,锁定计数应设置为1。每次线程重新锁定此互斥锁时,锁定计数应递增1。每次线程解锁互斥锁时,锁定计数减1。当锁定计数达到零时,互斥锁将可供其他线程获取。如果某线程试图解锁一个:不是本线程锁住的互斥锁、或未锁定的互斥锁,则返回错误。

⑤ 如果互斥锁类型为PTHREAD_MUTEX_DEFAULT,以下3种操作均会导致不可预知的结果:某个线程尝试二次锁定一个未解锁的互斥锁、如果某线程试图解锁一个:不是本线程锁住的互斥锁、或未锁定的互斥锁。

返回值:成功返回0,失败则直接返回错误号,而不是通过errno返回。

5、int pthread_mutex_trylock(pthread_mutex_t *mutex);

功能类似于pthread_mutex_lock,区别在于:pthread_mutex_trylock函数永不堵塞,对于一个已经被lock的锁(本线程或其他线程),如果该互斥锁是递归锁PTHREAD_MUTEX_RECURSIVE,那么本函数将返回0(成功),如果不是递归锁,那么本函数也不会堵塞,而是返回错误码。

返回:成功返回0,失败则直接返回错误号,而不是通过errno返回。

6、int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type);
填充attr指向的“互斥锁的属性”结构体,本函数第二实参会被填充到第一实参指向的结构中的成员中去。

被填充好的结构体将被作用pthread_mutex_init实参。

形参:@attr,属性变量的地址;
@type,互斥锁的类型,4个可选的值如下表格所示,每个值的意义请参考上面的pthread_mutex_lock函数的讲解。

返回与输出:成功则返回0,并把type的值写入attr地址中的结构体中去;失败直接返回错误码



猜你喜欢

转载自blog.csdn.net/qq_31073871/article/details/80955429
今日推荐