本文来自个人博客:https://dunkwan.cn
同步属性
就像线程具有属性一样,线程的同步对象也有属性。对于以下介绍的所有接口,若需要了解详情可通过命令man 3 + FunctionName
的方式进行查询。
互斥量属性
互斥量属性是与pthread_mutexattr_t
结构表示。对于互斥量的默认属性,可以通过使用PTHREAD_MUTEX_INITIALIZER
常量或者用指向互斥量属性结构的空指针作为参数调用pthread_mutex_init
函数;对于互斥量的非默认属性,可通过pthread_mutexattr_init
初始化pthread_mutexattr_t
结构,用pthread_mutexattr_destroy
来反初始化。
#include <pthread.h>
int pthread_mutexattr_init(pthread_mutexattr_t *attr);
int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);
两个函数的返回值:若成功,返回0;否则,返回错误编码。
以下对3个互斥量属性进行介绍。
进程共享属性
pthread_mutexattr_getpshared
和pthread_mutexattr_setpshared
函数来获取和修改进程共享属性。
#include <pthread.h>
int pthread_mutexattr_getpshared(const pthread_mutexattr_t *restrict attr, int *restrict pshared);
int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared);
两个函数的返回值:若成功,返回0;否则,返回错误编码。
健壮属性
pthread_mutexattr_getrobust
和pthread_mutexattr_setrobust
来获取和修改健壮属性。
#include <pthread.h>
int pthread_mutexattr_getrobust(const pthread_mutexattr_t *restrict attr, int *restrict robust);
int pthread_mutexattr_setrobust(pthread_mutexattr_t *attr, int robust);
两个函数的返回值:若成功,返回0;否则,返回错误编码。
类型属性
类型属性控制着互斥量的锁定特性,POSIX.1定义了4种类型。
类型 | 说明 |
---|---|
PTHREAD_MUTEX_NORMAL | 一种标准互斥量类型,不做任何特殊的错误检查或死锁检测。 |
PTHREAD_MUTEX_ERRORCHECK | 此互斥量类型提供错误检查 |
PTHREAD_MUTEX_RECURSIVE | 此互斥量类型允许同一线程在互斥量解锁之前对该互斥量进行多次加锁。 |
PTHREAD_MUTEX_DEFAULT | 此互斥量类型可以提供默认特性和行为。 |
上面四种类型的行为如下所示。
不占用时解锁?: 一个线程对被另一个线程加锁的互斥量进行解锁的情况。
在已解锁时解锁?: 当一个线程对已经解锁的互斥量进行解锁时将会发生什么,这通常是编码错误引起的。
互斥量类型 | 没有解锁时重新加锁? | 不占用时解锁? | 在已解锁时解锁? |
---|---|---|---|
PTHREAD_MUTEX_NORMAL | 死锁 | 未定义 | 未定义 |
PTHREAD_MUTEX_ERRORCHECK | 返回错误 | 返回错误 | 返回错误 |
PTHREAD_MUTEX_RECURSIVE | 允许 | 返回错误 | 返回错误 |
PTHREAD_MUTEX_DEFAULT | 未定义 | 未定义 | 未定义 |
pthread_mutexattr_gettype
和pthread_mutexattr_settype
可以获取和设置互斥量类型属性。
#include <pthread.h>
int pthread_mutexattr_gettype(const pthread_mutexattr_t *restrict attr, int *restrict type);
int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type);
两个函数返回值:若成功,返回0;否则,返回错误编码。
函数pthread_mutex_consistent
如果应用状态无法恢复,在线程对互斥量解锁以后,该互斥量将处于永久不可用状态。为了避免这样的问题,线程可以调用pthread_mutex_consistent
函数,指明与该互斥量相关的状态在互斥量解锁之前是一致的。
#include <pthread.h>
int pthread_mutex_consistent(pthread_mutex_t *mutex);
返回值:若成功,返回0;否则,返回错误编码。
如果线程没有使用pthread_mutex_consistent
对互斥量解锁,那么其他试图获取该互斥量的阻塞线程就会得到错误码ENOTRECOVERABLE
。如果发生这种情况,互斥量将不再可用。线程通过提前调用pthread_mutex_consistent
能让互斥量正常工作,这样它就可以持续被使用。
读写锁属性
pthread_rwlockattr_init
和pthread_rwlockattr_destroy
函数用于初始化和反初始化pthread_rwlockattr_t
结构。
#include <pthread.h>
int pthread_rwlockattr_init(pthread_rwlockattr_t *attr);
int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr);
两个函数的返回值:若成功,返回0;否则,返回错误编码。
读写锁唯一支持的属性是进程共享属性,pthread_rwlockattr_getpshared
和pthread_rwlockattr_setpshared
函数用于获取和设置读写锁的进程共享属性。
#include <pthread.h>
int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *restrict attr, int *restrict pshared);
int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr, int pshared);
两个函数的返回值:若成功,返回0;否则,返回错误编码。
条件变量属性
pthread_condattr_init
和pthread_condattr_destroy
函数用于初始化和反初始化条件变量属性。
#include <pthread.h>
int pthread_condattr_init(pthread_condattr_t *attr);
int pthread_condattr_destroy(pthread_condattr_t *attr);
两个函数返回值:若成功,返回0;否则,返回错误编码。
Single UNIX Specification 目前定义了条件变量的两个属性:进程共享属性和时钟属性。pthread_condattr_getpshared
和pthread_condattr_setshared
用于获取和设置进程共享属性。
#include <pthread.h>
int pthread_condattr_getpshared(const pthread_condattr_t *restrict attr, int *restrict pshared);
int pthread_condattr_setpshared(pthread_condattr_t *attr, int pshared);
两个函数返回值:若成功,返回0;否则,返回错误编码。
时钟属性控制计算pthread_cond_timedwait
函数的超时参数采用的是哪个时钟。
pthread_condattr_getclock
和pthread_condattr_setclock
函数用于获取和设置时钟ID。
#include <pthread.h>
int pthread_condattr_getclock(const pthread_condattr_t *restrict attr, clockid_t *restrict clock_id);
int pthread_condattr_setclock(pthread_condattr_t *attr, clockid_t clock_id);
两个函数返回值:若成功,返回0;否则,返回错误编码。
屏障属性
pthread_barrierattr_init
和pthread_barrierattr_destroy
用于初始化和反初始化屏障属性对象。
#include <pthread.h>
int pthread_barrierattr_init(pthread_barrierattr_t *attr);
int pthread_barrierattr_destroy(pthread_barrierattr_t *attr);
函数返回值:若成功,返回0;否则,返回错误编码。
目前定义的屏障属性只有进程共享属性。pthread_barrierattr_getpshared
和pthread_barrierattr_setpshared
用于获取和设置屏障的进程共享属性。
#include <pthread.h>
int pthread_barrierattr_getpshared(const pthread_barrierattr_t *restrict attr, int *restrict pshared);
int pthread_barrierattr_setpshared(pthread_barrierattr_t *attr, int pshared);
两个函数返回值:若成功,返回0;否则,返回错误编码。