kzh*_*dev 8 c++ condition-variable c++11
打算修改变量的线程必须
- 获取std :: mutex(通常通过std :: lock_guard)
- 在锁定时执行修改
- 在std :: condition_variable上执行notify_one或notify_all(不需要保持锁定以进行通知)
即使共享变量是原子的,也必须在互斥锁下对其进行修改,以便将修改正确地发布到等待的线程.
我不太明白,为什么修改原子变量需要锁定.请参阅以下代码段:
static std::atomic_bool s_run {true};
static std::atomic_bool s_hasEvent {false};
static std::mutex s_mtx;
static std::condition_variabel s_cv;
// Thread A - the consumer thread
function threadA()
{
while (s_run)
{
{
std::unique_lock<std::mutex> lock(s_mtx);
s_cv.wait(lock, [this]{
return m_hasEvents.load(std::memory_order_relaxed);
});
}
// process event
event = lockfree_queue.pop();
..... code to process the event ....
}
}
// Thread B - publisher thread
function PushEvent(event)
{
lockfree_queque.push(event)
s_hasEvent.store(true, std::memory_order_release);
s_cv.notify_one();
}
Run Code Online (Sandbox Code Playgroud)
在PushEvent函数中,我没有获取s_mtx,因为s_hasEvent是一个原子变量,而队列是lockfree.无法获得s_mtx锁定的问题是什么?
正如Yakk对你所关联的问题的回答所指出的那样,是为了防止这一系列事件导致错过唤醒:
m_hasEvents.load(std::memory_order_relaxed);并返回值false. s_hasEvents_cv.notify_one(). false闭包返回的结果,确定没有挂起事件. 这意味着notify_one()错过了调用,即使队列中有事件准备就绪,条件变量也会阻塞.
如果在互斥锁被锁定时完成对共享变量的更新,则步骤4不可能在步骤2和7之间发生,因此条件变量对事件的检查会得到一致的结果.使用发布者和消费者使用的互斥锁要么s_hasEvent在第1步之前发生存储(因此闭包加载值true并且永远不会阻塞条件变量),要么在步骤8之后发生(因此notify_one()调用将唤醒它) .
| 归档时间: |
|
| 查看次数: |
579 次 |
| 最近记录: |