RocksDB源代码中的c++内存顺序void WriteThread::SetState(Writer* w,uint8_t new_state)

wqnecbli  于 2023-10-20  发布在  其他
关注(0)|答案(1)|浏览(116)

我最近一直在阅读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++中的记忆顺序,我不知道上面的是否正确,伙计们,你们能给予我正确的答案吗?

s3fp2yjn

s3fp2yjn1#

  • 是否可以这样写?* 如果没有看到其他代码,即等待w->StateCV()或使用w->state,则无法回答“是”。因此,答案是不,它不能。如果像上面所示的那样重写它,就会破坏原来的函数逻辑。

1.新代码中的w->state可以在assert()store()之间改变。
1.新代码中的w->state可以在store()notify_one()之间更改。

相关问题