我最近一直在阅读rocksdb的源代码,但我遇到了一个问题,我不能弄清楚,想征求意见
void WriteThread::SetState(Writer* w, uint8_t new_state) {
assert(w);
auto state = w->state.load(std::memory_order_acquire);
if (state == STATE_LOCKED_WAITING ||
!w->state.compare_exchange_strong(state, new_state)) {
assert(state == STATE_LOCKED_WAITING);
std::lock_guard<std::mutex> guard(w->StateMutex());
assert(w->state.load(std::memory_order_relaxed) != new_state);
w->state.store(new_state, std::memory_order_relaxed);
w->StateCV().notify_one();
}
}
代码auto state = w->state.load(std::memory_order_acquire);
我的第一个问题:为什么不使用memory_order_relaxed,因为对于if (state == STATE_LOCKED_WAITING
.包含的块取决于变量状态,不应该在w->state.load
代码之前重新排列,因此不需要使用std::memory_order_acquire
。
我的第二个问题是:对于代码段
std::lock_guard<std::mutex> guard(w->StateMutex());
assert(w->state.load(std::memory_order_relaxed) != new_state);
w->state.store(new_state, std::memory_order_relaxed);
w->StateCV().notify_one();
它可以写成下面这样吗?
assert(w->state.load(std::memory_order_relaxed) != new_state);
w->state.store(new_state, std::memory_order_relaxed);
std::lock_guard<std::mutex> guard(w->StateMutex());
w->StateCV().notify_one();
我不太清楚为什么这里需要加锁互斥,我想w->state.store
已经得到了最新的值,一定是我的理解有问题,希望大家能纠正!
我正在学习c++中的记忆顺序,我不知道上面的是否正确,伙计们,你们能给予我正确的答案吗?
1条答案
按热度按时间s3fp2yjn1#
w->StateCV()
或使用w->state
,则无法回答“是”。因此,答案是不,它不能。如果像上面所示的那样重写它,就会破坏原来的函数逻辑。1.新代码中的
w->state
可以在assert()
和store()
之间改变。1.新代码中的
w->state
可以在store()
和notify_one()
之间更改。