C pthread条件循环

C pthread条件循环,c,multithreading,pthreads,C,Multithreading,Pthreads,我看到的使用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(&

我看到的使用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);

使用条件变量时,如果线程应该继续,则始终存在一个布尔谓词,该谓词涉及与每个条件等待相关联的共享变量。可能会发生pthread_cond_timedwait()或pthread_cond_wait()函数的虚假唤醒。由于pthread_cond_timedwait()或pthread_cond_wait()的返回并不意味着与此谓词的值有关的任何内容,因此应在此类返回时重新计算谓词


根据POSIX的要求,
while
循环是重新评估谓词的一种非常标准的方法。

如果
可以,但很少使用。您只需确保应用程序的状态是在您走出
wait
时。通常,您必须确保只在另一端使用
pthread\u cond\u signal
(而不是
broadcast
),例如,有两个原因。一种是虚假唤醒,如其他答案中所述。另一个是真正的觉醒。想象一下:

在保护队列的同一条件变量上阻塞了两个线程A和B,队列为空。一些线程将作业放入队列,唤醒线程a。另一个线程将作业放入队列,唤醒线程B。线程a首先开始运行,然后执行第一个作业。它返回到
if
并看到条件仍然为真(因为还有第二个作业),因此它也执行该作业。现在线程B从
pthread\u cond\u wait
返回处理器,但谓词不是false,因为队列是空的


只有当其他线程要求唤醒您时,您才知道谓词为true。您无法知道,当您最终得到调度并能够重新获取互斥时,它仍然是正确的。

根据R的回答,允许虚假唤醒,这意味着无论通过广播使用信号,if都不能保证安全。