这个问题来源于一个demo的代码测试的时候,代码简化之后如下
#include<pthread.h>
#include<stdio.h>
int main(){
pthread_mutex_t lock;
pthread_mutex_init(&lock, NULL);
pthread_mutex_lock(&lock);
printf("111\n");
pthread_mutex_lock(&lock);
printf("222\n");
}
本来我期望的结果是输出111,然后进程会阻塞在第二个pthread_mutex_lock处。但是在Linux ubuntu上编译执行后,输出为:
111
222
程序并不会阻塞。然后我用同样的代码在Mac OS上编译运行,结果是:
111
程序阻塞…
这个现象有点奇怪,为什么在ubuntu上没有阻塞呢?于是查了一下相关资料,原来是互斥量类型属性的问题。问题出在pthread_mutex_init(&lock, NULL);这一句,下面把程序做一下简单的修改:
#include<pthread.h>
#include<stdio.h>
int main(){
pthread_mutex_t lock;
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&lock, &attr);
pthread_mutex_lock(&lock);
printf("111\n");
pthread_mutex_lock(&lock);
printf("222\n");
}
修改后的代码在ubuntu和Mac OS上运行都不会阻塞,如果把pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)这一句中的PTHREAD_MUTEX_RECURSIVE换成PTHREAD_MUTEX_NORMAL,那么在ubuntu和Mac上都会阻塞。
到这里原因已经很明显了,在最初的代码中pthread_mutex_init(&lock, NULL); 互斥量属性设置的是NULL,所以互斥量的类型属性就被设为了PTHREAD_MUTEX_DEFAULT,这个互斥量类型提供默认的行为,既操作系统在实现它的时候可以把这种类型任自由地映射到其它的互斥量类型属性中的一种:PTHREAD_MUTEX_RECURSIVE、PTHREAD_MUTEX_NORMAL或者PTHREAD_MUTEX_ERRORCHECK。同样的代码在ubuntu和Mac上会有不同的行为,如最初的代码的输出所示。