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

How to fix race condition for condition variable wait/notify

这个问题的答案是错误的,因为它有可能死锁。 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);

现在,如果您删除注释为 ******** 的两行,竞争条件将得到解决,并且线程 1 在拥有锁时等待而线程 2 卡在锁定 x 处会引入死锁的机会。

你困惑的根源是你对条件变量的误解。它们的固有特性是锁释放和进入等待模式是自动完成的,即两者之间没有任何反应。

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

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

Atomically releases lock, blocks the current executing thread, and adds it to the list of threads waiting on *this. The thread will be unblocked when notify_all() or notify_one() is executed. It may also be unblocked spuriously. When unblocked, regardless of the reason, lock is reacquired and wait exits. If this function exits via exception, lock is also reacquired. (until C++14)