1

我对读-修改-写操作背后的机制有点困惑,例如 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),然后添加旧值?如果不是,他们如何实现这一目标?

4

1 回答 1

1

这不可能。它是通过特定于平台的原子指令来实现的,例如在 x86 中使用“lock”前缀或在其他平台上使用“ll/sc”。内存排序控制观察到的对不同内存位置的修改顺序。这是与原子性不同的问题。

于 2013-09-08T14:37:15.833 回答