之前在网上看到很多资料都说条件变量的互斥锁是用来保护条件变量的,没用之前觉得挺有道理的。后来自己真正用的时候,才发现并不是那么回事。例如下面的例子:
pthread_mutex_t cmutex;
pthread_cond_t cond;
pthread_mutex_init(&cmutex, NULL);
pthread_cond_init(&cond, NULL);
pthread_mutex_lock(&cmutex)
while(flage == false){
pthread_cond_wait(&cond, &cmutex);
}
pthread_mutex_unlock(&cmutex);
加锁等待条件变量
pthread_mutex_lock(&cmutex)
flage = true;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&cmutex);
加锁通知条件变量
上述程序中,如果加锁是为了保护条件变量,那么将会产生死锁。因为pthread_cond_wait(&cond, &cmutex)获得了互斥锁,一直在阻塞等待条件变量的信息,自然pthread_cond_signal(&cond)部分是获得不了互斥锁的,所以会产生死锁。
上述只是给大家举个例子,实际上该互斥锁是为了保护flage变量的。当我们在用pthread_cond_wait(&cond, &cmutex);等待条件变量通知时,容易产生虚假唤醒,这样会导致运行结果不正确。所以我们往往在外层加一个循环和变量来判断,是不是虚假唤醒(例如不是虚假唤醒就置flage为true)。pthread_cond_wait(&cond, &cmutex)是三步组成。真实实现如下:
pthread_mutex_lock(&cmutex)
while(flage == false){
pthread_cond_wait(&cond, &cmutex);=
{1、pthread_mutex_unlock(&cmutex);
2、 pthread_cond_wait();等待唤醒,唤醒后再加锁,这样通知条件变量的语句才有机会加锁
3、pthread_mutex_lock(&cmutex);
}
}
pthread_mutex_unlock(&cmutex);
上述分解后的步骤可以看到,整个过程都是在保护flage变量的,设计的也很巧妙。
第一篇博客,写的可能不是很清楚,谅解。