Condition Variable - Wait/Notify Race Condition

删除回忆录丶 提交于 2019-12-22 07:58:09

问题


I'll present some code first since explaining is easier that way. Assume that mutexes are correctly used with the condition variables to keep it simple:

// Thread 1
while(1)
{
    conditionVariable.wait();
    // Do some work
}

// Thread 2
while(1)
{
    // Do some work
    conditionVariable.notify_one();
}

// Thread 3
while(1)
{
    // Do some work
    conditionVariable.notify_one();
}

What I would like to achieve is that thread 1 is guaranteed to be waiting on the condition variable when thread 2 or Thread 3 notifies. As the code stands, there is a large gap between notify_one() and wait() in the form of some other code marked by the comments. This gap means sometimes notify_one() is called before gets a chance to call wait().

After some thought it seems that the closest I can get to this is to use some form of mutual exclusion before notify_one() and before wait() (at the start of thread 1's loop). However, no matter how this is done, there is still a small gap (1 line of code) between the mutual exclusion and the wait(), allowing Threads 2 and 3 to call notify_one() just before Thread 1 calls wait(). It's unlikely, but possible.

I also thought about using the wait() predicate to flag a boolean allowing the other threads to notify. I guess this would work since wait() is atomic, but I'm wondering if there is a better way. Perhaps I am approaching this incorrectly.

In summary: how can I ensure thread 1 is waiting before allowing threads 2 and 3 to notify?


回答1:


In short: think about condition variables as a method to notify other threads that something has changed, not just as a signal.

In order to do this, the condition variable should accompany a condition (simple example: an integer is incremented) that can be handled by the receiving thread.

Now, to solve your problem, thread 1 can use a condition variable accompanied by a ready boolean to signal the other threads when it is ready to receive the condition variable signal, but you better check first whether the original condition variable can be used as described here.

pseudo code based on question (proper locking of conditionVariable still needed):

// Thread 1
while(1)
{
    lockReady();
    ready = true;
    unlockReady();
    readyCV.notify_one();
    conditionVariable.wait();

    // Do some work
}

// Thread 2
while(1)
{
    lockReady();
    while (! ready) readyCV.wait();
    ready = false;
    unlockReady();
    // Do some work
    conditionVariable.notify_one();
}

// Thread 3
while(1)
{
    lockReady();
    while (! ready) readyCV.wait();
    ready = false;
    unlockReady();
    // Do some work
    conditionVariable.notify_one();
}

see also my previous answer



来源:https://stackoverflow.com/questions/21304375/condition-variable-wait-notify-race-condition

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!