我对读-修改-写操作背后的机制有点困惑,例如 fetch_add。当使用宽松的内存顺序时,他们如何避免读取旧值并得到错误的结果?这是演示代码:
std::atomic<int> global_counter = 0;
//thread 0
int counter0 = global_counter.fetch_add(1, std::memory_order_relaxed);
assert(counter0 > 0);
//thread 1
int counter1 = global_counter.fetch_add(1, std::memory_order_relaxed);
assert(counter1 > 0);
因为两个 fetch_add 动作都用 std::memory_order_relaxed 标记,所以只保证它们的原子性。两个线程中的 fetch_add 操作是否有可能读取 global_counter 的旧值(即 0),然后添加旧值?如果不是,他们如何实现这一目标?