为什么 std::condition_variable wait() 需要一个 std::unique_lock 参数?

Why does std::condition_variable wait() require a std::unique_lock arg?

我的帖子不需要加锁。 std::unique_lock 在构造时锁定线程。我只是使用 cond_var.wait() 作为避免忙等待的一种方式。我基本上通过将 unique_lock 放在一个很小的范围内来绕过自动锁定,从而在它离开这个小范围后销毁唯一锁。此外,如果相关的话,只有一个消费者线程

{
std::unique_lock<std::mutex> dispatch_ul(dispatch_mtx);
pq_cond.wait(dispatch_ul);
}

是否有更好的选择来避免 unique_lock 不必要的自动锁定功能?我正在寻找一个无互斥选项来简单地向线程发出信号,我知道 std::condition_variable_any 但这需要某种互斥锁,这在我的情况下又是不必要的。

你需要一把锁来防止这个常见的新手错误:

  1. 生产者线程生产一些东西,
  2. 生产者线程调用 some_condition.notify_all()
  3. 生产者线程暂时空闲,

同时:

  1. 消费者线程调用 some_condition.wait(...)
  2. 消费者线程等待,...
  3. 等待,...
  4. 然后等待。

条件变量不是标志。它不记得它被通知过。如果生产者在消费者进入wait()调用之前调用notify_one()notify_all(),则通知“丢失”。

为了防止丢失通知,必须有一些共享数据告诉消费者是否需要等待,并且必须有锁来保护共享数据。

生产者应该:

  1. 锁上锁,
  2. 更新共享数据,
  3. 通知条件变量,
  4. 解除锁定

然后消费者必须:

  1. 锁上锁,
  2. 检查共享数据是否需要等待,
  3. 如有需要请稍候,
  4. 随便吃,
  5. 解除锁定。

消费者需要将锁传递给 wait(...) 调用,以便 wait(...) 可以暂时解锁,然后 re-lock 在返回之前将其解锁。如果 wait(...) 没有解锁锁,那么生产者将永远无法到达 notify() 调用。