为什么 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 但这需要某种互斥锁,这在我的情况下又是不必要的。
你需要一把锁来防止这个常见的新手错误:
- 生产者线程生产一些东西,
- 生产者线程调用
some_condition.notify_all()
、
- 生产者线程暂时空闲,
同时:
- 消费者线程调用
some_condition.wait(...)
- 消费者线程等待,...
- 等待,...
- 然后等待。
条件变量不是标志。它不记得它被通知过。如果生产者在消费者进入wait()
调用之前调用notify_one()
或notify_all()
,则通知“丢失”。
为了防止丢失通知,必须有一些共享数据告诉消费者是否需要等待,并且必须有锁来保护共享数据。
生产者应该:
- 锁上锁,
- 更新共享数据,
- 通知条件变量,
- 解除锁定
然后消费者必须:
- 锁上锁,
- 检查共享数据是否需要等待,
- 如有需要请稍候,
- 随便吃,
- 解除锁定。
消费者需要将锁传递给 wait(...)
调用,以便 wait(...)
可以暂时解锁,然后 re-lock 在返回之前将其解锁。如果 wait(...)
没有解锁锁,那么生产者将永远无法到达 notify()
调用。
我的帖子不需要加锁。 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 但这需要某种互斥锁,这在我的情况下又是不必要的。
你需要一把锁来防止这个常见的新手错误:
- 生产者线程生产一些东西,
- 生产者线程调用
some_condition.notify_all()
、 - 生产者线程暂时空闲,
同时:
- 消费者线程调用
some_condition.wait(...)
- 消费者线程等待,...
- 等待,...
- 然后等待。
条件变量不是标志。它不记得它被通知过。如果生产者在消费者进入wait()
调用之前调用notify_one()
或notify_all()
,则通知“丢失”。
为了防止丢失通知,必须有一些共享数据告诉消费者是否需要等待,并且必须有锁来保护共享数据。
生产者应该:
- 锁上锁,
- 更新共享数据,
- 通知条件变量,
- 解除锁定
然后消费者必须:
- 锁上锁,
- 检查共享数据是否需要等待,
- 如有需要请稍候,
- 随便吃,
- 解除锁定。
消费者需要将锁传递给 wait(...)
调用,以便 wait(...)
可以暂时解锁,然后 re-lock 在返回之前将其解锁。如果 wait(...)
没有解锁锁,那么生产者将永远无法到达 notify()
调用。