如何修复条件变量wait / notify的竞争条件

时间:2017-07-27 20:54:07

标签: c++ deadlock race-condition condition-variable

回答这个问题是错误的,因为它有机会陷入僵局。 Condition Variable - Wait/Notify Race Condition

我找不到解决竞争条件或死锁问题的解决方案。

想象一下,我们有两个主题。现在的目标如下。

first condition:
Thread 1 Waits
Thread 2 Notifies

second condition:
Thread 2 Notifies
Thread 1 Should not wait and continue normal execution.

如果没有通知队列,如何才能正确实施?因为我希望这部分代码尽可能快地运行并使用布尔值而不是将项添加到队列中。也只有2个线程,所以使用队列对我来说似乎有点过分了。

有竞争条件时的伪代码:

Thread 1:
lock(x);
if(!signaled)
{
    unlock(x); // ********
    // still small gap, how to avoid?
    cv.wait(); // forget spurious wakeup for sake of simplicity 
    signaled = false;
}
else // ********
    unlock(x);

Thread 2:
lock(x);
signaled = true;
cv.notify();
unlock(x);

现在,如果删除两行注释为********竞争条件将被解决并且将引入死锁的可能性,其中Thread1在拥有锁时等待并且Thread2在锁定x时被卡住。

1 个答案:

答案 0 :(得分:3)

你混淆的根源是你对条件变量的误解。它们的固有特征是锁定释放和进入等待模式是原子,即两者之间没有任何反应。

因此,在变量进入等待模式之前,不会对变量进行任何修改,因为不会释放锁定。这是任何符合conditional_variable实现的基本保证,例如,以下是std::conditional_variable参考页面的摘录:

http://en.cppreference.com/w/cpp/thread/condition_variable/wait

  

原子释放锁定,阻止当前正在执行的线程,以及   将它添加到等待* this的线程列表中。线程将是   执行notify_all()或notify_one()时取消阻止。它也可能   虚假地畅通无阻。无阻塞时,无论原因如何,   锁被重新获取并等待退出。如果此功能退出通过   异常,也会重新获取锁定。 (直到C ++ 14)