就像线程具有属性一样,用于线程互斥的互斥量的也有相应的属性,互斥量属性的数据类型是用pthread_mutexattr_t结构来表示的,在使用互斥量前必须初始化。
创建互斥量有两种方法:静态创建和动态创建。对于静态创建而言,POSIX定义了一个宏PTHREAD_MUTEX_INITIALIZER来静态初始化互斥量,使用方法如下:
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
对于动态创建互斥量则是使用pthread_mutex_init函数初始化互斥量,参数attr用于指定互斥量的属性,互斥量用完对应的要调用pthread_mutex_destroy函数销毁互斥量,具体如何动态创建互斥量,前面已经介绍了,这里就不再赘述了(参考:27-线程同步——互斥量)。
pthread_mutexattr_t是互斥锁属性的数据类型,表示互斥锁的一些属性相关的信息。
//初始化互斥锁属性
pthread_mutexattr_init(pthread_mutexattr_t attr);
//销毁互斥锁属性
pthread_mutexattr_destroy(pthread_mutexattr_t attr);
//用于获取互斥锁属性
int pthread_mutexattr_getpshared(const pthread_mutexattr_t *restrict attr , int *restrict pshared);
//用于设置互斥锁属性
int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr , int pshared);
参数说明:
attr表示互斥锁属性
pshared表示互斥量的共享属性有以下两种值可取:
PTHREAD_PROCESS_PRIVATE:锁只能用于一个进程内部的两个线程进行排斥(默认情况)。
PTHREAD_PROCESS_SHARED:锁可用于两个不同进程中的线程进行排斥,使用还需要在共享内存中分配互斥量,然后再为互斥量指定该属性就可以了。
//获取互斥锁类型
int pthread_mutexattr_gettype(const pthread_mutexattr_t *restrict attr , int *restrict type);
//设置互斥锁类型
int pthread_mutexattr_settype(const pthread_mutexattr_t *restrict attr , int type);
#include
#include
#include
#include
int main(int argc , char *args[]){
//定义互斥锁
pthread_mutex_t mutex;
if(argc < 2){
printf("input mutex type\n");
return -1;
}
//定义互斥锁属性
pthread_mutexattr_t mutexattr;
//初始化互斥锁属性
pthread_mutexattr_init(&mutexattr);
//设置互斥锁类型,error:检错互斥锁,normal:标准互斥锁,recursive:递归互斥锁
if(!strcmp(args[1] , "error")){
pthread_mutexattr_settype(&mutexattr , PTHREAD_MUTEX_ERRORCHECK);
printf("set error succes\n");
}else if(!strcmp(args[1], "normal")){
pthread_mutexattr_settype(&mutexattr , PTHREAD_MUTEX_NORMAL);
printf("set normal succes\n");
}else if(!strcmp(args[1], "recursive")){
pthread_mutexattr_settype(&mutexattr , PTHREAD_MUTEX_RECURSIVE);
printf("set recursive\n");
}
//初始化互斥锁
pthread_mutex_init(&mutex , &mutexattr);
//第一次上锁
if(pthread_mutex_lock(&mutex) != 0){
printf("lock failed\n");
}else{
printf("lock succes\n");
}
//第二次上锁
if(pthread_mutex_lock(&mutex) != 0){
printf("lock failed\n");
}else{
printf("lock succes\n");
}
//加锁几次,同样也要释放几次
pthread_mutex_unlock(&mutex);
pthread_mutex_unlock(&mutex);
//销毁互斥锁属性和互斥锁
pthread_mutexattr_destroy(&mutexattr);
pthread_mutex_destroy(&mutex);
return 0;
}
./pthread_lock_type error,设置检错互斥锁:
检错互斥锁第一次加锁会成功,第二次加锁会失败返回错误信息,并不会阻塞。
./pthread_lock_type normal,设置标准互斥锁:
第一次加锁会成功,第二次加锁会失败并阻塞。
./pthread_lock_type recursive,设置递归互斥锁:
递归互斥锁第一次加锁会成功,第二次加锁也会成功,内部会计数。