为什么在等待条件变量时需要while循环

时间:2011-10-14 10:03:01

标签: c linux pthreads signals

说你有这个代码

pthread_mutex_lock(&cam->video_lock);
while(cam->status == WAIT_DISPLAY) // <-- Why is this a 'while' and not an 'if'?
    pthread_cond_wait(&cam->video_cond, &cam->video_lock);
pthread_mutex_unlock(&cam->video_lock);

我的问题是,为什么你需要一个while循环。不会 pthread_cond_wait 等到信令线程信号 cam_video_cond ?好的,我知道当调用 pthread_cond_wait 时,你可能会遇到 cam-&gt;状态不等于 WAIT_DISPAY 的情况,但在这种情况下您可以通过 if 条件检查它,而不是使用 while

我在这里遗漏了什么吗?我对 pthread_cond_wait 的理解是,如果 cam_video_cond 未发出信号,它只会等待无限。此外,它会在调用时解锁 cam_video_lock 互斥锁,但是当发出条件信号时,在返回之前,它会重新锁定 cam_video_lock 。我是对的吗?

3 个答案:

答案 0 :(得分:18)

  

建议所有线程在返回后检查条件   来自 pthread_cond_wait 因为条件有几个原因   可能不是真的。其中一个原因是虚假的唤醒;那是,   即使没有线程发出信号,线程也可能被唤醒   条件。

来源:Spurious wakeup

答案 1 :(得分:12)

虚假的唤醒是一个原因,但合法但无关的唤醒是另一个原因。

考虑:

  1. 您将作业放在队列中。

  2. 您发出条件变量信号,唤醒线程A.

  3. 您将作业放在队列中。

  4. 您发出条件变量信号,唤醒线程B.

  5. 线程A被安排,完成第一份工作。

  6. 线程A发现队列非空并执行第二个作业。

  7. 线程B被调度,被唤醒,但发现队列仍然是空的。

答案 2 :(得分:2)

出于性能原因,POSIX API允许操作系统唤醒您的线程,即使条件尚未满足(称为spurious wakeup)。