Linux编程接口书有一段代码(生产者/消费者)来展示条件变量的工作原理:
static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
static int avail = 0;
while (TRUE) {
s = pthread_mutex_lock(&mtx);
while (avail == 0) { /* Wait for something to consume */
s = pthread_cond_wait(&cond, &mtx);
}
while (avail > 0) { /* Consume all available units */
avail--;
}
s = pthread_mutex_unlock(&mtx);
}
为什么我们在pthread_mutex_lock
中使用while
?为什么我们不在if
中使用它?
答案 0 :(得分:12)
因为允许pthread_cond_signal()唤醒多个等待条件变量的线程。因此,一旦你醒来,你必须仔细检查一下情况,因为其他一些线程可能已经唤醒并在你之前改变它。
如果您知道只有一个线程在等待,并且您确定将来没有人会修改程序中其他地方的代码以添加另一个等待的线程,那么您可以使用if
。但你永远不会知道,所以总是使用while
。
[更新]
正如ninjalj在评论中指出的那样,我的回答是不完整的,因为没有提到“虚假的唤醒”。例如,POSIX标准清楚地表明,如果等待线程接收到一个信号(例如,通过kill()),即使没有其他线程发信号通知条件变量,pthread_cond_wait()也可以返回0。标准是不明确的(在我看来)是否可以毫无理由地唤醒等待线程...但底线是:始终使用while
,而不是{ {1}}。