我见过使用pthread_cond_wait的典型模式是:
pthread_mutex_lock(&lock);
while (!test)
pthread_cond_wait(&condition, &lock);
pthread_mutex_unlock(&lock);
为什么不能使用if语句而不是while循环。
pthread_mutex_lock(&lock);
if (!test)
pthread_cond_wait(&condition, &lock);
pthread_mutex_unlock(&lock);
答案 0 :(得分:9)
http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_cond_timedwait.html
使用条件变量时,总会有一个布尔谓词,涉及与每个条件等待关联的共享变量,如果线程应该继续,则为true。可能会发生pthread_cond_timedwait()或pthread_cond_wait()函数的虚假唤醒。由于从pthread_cond_timedwait()或pthread_cond_wait()返回并不意味着有关此谓词的值的任何内容,因此应在返回时重新评估谓词。
根据POSIX的要求,while
循环是一种非常标准的重新评估谓词的方法。
答案 1 :(得分:1)
if
可能但很少使用。您只需要确保应用程序的状态与wait
中的状态一致。通常你必须确保你只在另一端使用pthread_cond_signal
(而不是broadcast
),例如。
答案 2 :(得分:1)
有两个原因。其中一个是虚假的唤醒,如其他答案所述。另一种是真正的唤醒。想象一下:
您有两个线程A和B,在保护队列的相同条件变量上被阻塞,队列为空。一些线程将一个作业放入队列,唤醒线程A.另一个线程将一个作业放入队列,唤醒线程B.线程A首先开始运行,然后执行第一个作业。它回到if
并看到条件仍然是真的(因为有第二个工作),所以它也做了那个工作。现在,线程B从pthread_cond_wait
返回处理器,但是谓词不是假的,因为队列是空的。
当其他一些线程要求你被唤醒时,你才知道谓词是真的。当你最终完成预定并且能够重新获得互斥锁时,你无法知道它仍然是真的。