在多个内核执行时,c ++ 11中的读取 - 修改 - 写入操作如何实现相互可见性?

时间:2013-09-08 14:25:22

标签: multithreading c++11 concurrency

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

1 个答案:

答案 0 :(得分:1)

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