Why is a while loop needed around pthread wait conditions?

后端 未结 2 1150
既然无缘
既然无缘 2020-12-07 10:41

I\'m learning pthread and wait conditions. As far as I can tell a typical waiting thread is like this:

pthread_mutex_lock(&m);
while(!condition)
     pth         


        
相关标签:
2条回答
  • 2020-12-07 11:04

    The real reason you should put pthread_cond_wait in a while loop is not because of spurious wakeup. Even if your condition variable did not have spurious wakeup, you would still need the loop to catch a common type of error. Why? Consider what can happen if multiple threads wait on the same condition:

    Thread 1                         Thread 2           Thread 3
    check condition (fails)
    (in cond_wait) unlock mutex
    (in cond_wait) wait
                                     lock mutex
                                     set condition
                                     signal condvar
                                     unlock mutex
                                                        lock mutex
                                                        check condition (succeeds)
                                                        do stuff
                                                        unset condition
                                                        unlock mutex
    (in cond_wait) wake up
    (in cond_wait) lock mutex
    <thread is awake, but condition
    is unset>
    

    The problem here is that the thread must release the mutex before waiting, potentially allowing another thread to 'steal' whatever that thread was waiting for. Unless it is guaranteed that only one thread can wait on that condition, it is incorrect to assume that the condition is valid when a thread wakes up.

    0 讨论(0)
  • 2020-12-07 11:14

    Suppose you don't check the condition. Then usually you can't avoid the following bad thing happening (at least, you can't avoid it in one line of code):

     Sender                             Receiver
    locks mutex
    sets condition
    signals condvar, but nothing 
      is waiting so has no effect
    releases mutex
                                        locks mutex
                                        waits. Forever.
    

    Of course your second code example could avoid this by doing:

    pthread_mutex_lock(&m);
    if (!condition) pthread_cond_wait(&cond, &m);
    // Thread stuff here
    pthread_mutex_unlock(&m);
    

    Then it would certainly be the case that if there is only ever at most one receiver, and if cond_signal were the only thing that could wake it up, then it would only ever wake up when the condition was set and hence would not need a loop. nos covers why the second "if" isn't true.

    0 讨论(0)
提交回复
热议问题