Why do you need a while loop while waiting for a c

2019-01-22 10:01发布

问题:

Say you have this code

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);

My question is, why do you need a while loop here. Wouldn't pthread_cond_wait just wait until the signalling thread signals cam_video_cond? OK, I know you might have a case where cam->status is not equal to WAIT_DISPAY when pthread_cond_wait is called, but in that case you could just check it through an if condition rather than using while.

Am I missing something here? My understanding of pthread_cond_wait is that it just waits for infinite if cam_video_cond is not signalled. Moreover, it unlocks the cam_video_lock mutex when called, but when the condition is signalled, before returning, it relocks cam_video_lock. Am I right?

回答1:

It is recommended that all threads check the condition after returning from pthread_cond_wait because there are several reasons the condition might not be true. One of these reasons is a spurious wakeup; that is, a thread might get woken up even though no thread signalled the condition.

Source : Spurious wakeup



回答2:

Spurious wakeups are one reason, but legitimate but extraneous wakeups are another.

Consider:

  1. You put a job on a queue.

  2. You signal the condition variable, waking thread A.

  3. You put a job on a queue.

  4. You signal the condition variable, waking thread B.

  5. Thread A gets scheduled, does the first job.

  6. Thread A finds the queue non-empty and does the second job.

  7. Thread B gets scheduled, having been woken, but finds the queue still empty.



回答3:

For performance reasons, the POSIX API allows the OS to wake up your thread even if the condition has not been fulfilled (that's called a spurious wakeup).