C++ 中的原子操作和可见性
atomic operations and visibility in C++
考虑以下代码:
static std::atomic<int> x;
// Thread 1
x.store(7, std::memory_order_relaxed);
// Thread 2
x.load(std::memory_order_relaxed);
进一步假设 线程 2 执行了 load
几个周期after 线程 1 执行了 store
.
是否保证 线程 2 会在所有硬件平台上读取值 7
?换句话说,在 线程 1 执行了 store
之后,是否保证值 7 对线程立即可见,稍后对同一变量进行轻松加载?
是的,它将是可见的。
关于松弛的记忆顺序以及它们与更强的记忆顺序相比有何作用,这已成为一个普遍的问题。
强于松弛的内存顺序会做以下两件事:
- 同步非原子数据
- 防止在同一线程中重新排序指令
不同的顺序保证不同的同步策略(只读,只写,读和写)和不同的重排序预防(只在指令前执行,只在指令后执行或两者)。放松的内存顺序不能保证其中任何一个,它只能保证原子变量在线程中可见。
在您的示例中,除了一个线程中的存储和另一个线程中的加载之外,没有其他指令。另外,没有跨线程同步的非原子内存,唯一的内存已经是原子的。
所以没有必要使用比memory_order_relaxed
更重的东西。上面的代码片段是有效的,会产生想要的结果。
考虑以下代码:
static std::atomic<int> x;
// Thread 1
x.store(7, std::memory_order_relaxed);
// Thread 2
x.load(std::memory_order_relaxed);
进一步假设 线程 2 执行了 load
几个周期after 线程 1 执行了 store
.
是否保证 线程 2 会在所有硬件平台上读取值 7
?换句话说,在 线程 1 执行了 store
之后,是否保证值 7 对线程立即可见,稍后对同一变量进行轻松加载?
是的,它将是可见的。 关于松弛的记忆顺序以及它们与更强的记忆顺序相比有何作用,这已成为一个普遍的问题。
强于松弛的内存顺序会做以下两件事:
- 同步非原子数据
- 防止在同一线程中重新排序指令
不同的顺序保证不同的同步策略(只读,只写,读和写)和不同的重排序预防(只在指令前执行,只在指令后执行或两者)。放松的内存顺序不能保证其中任何一个,它只能保证原子变量在线程中可见。
在您的示例中,除了一个线程中的存储和另一个线程中的加载之外,没有其他指令。另外,没有跨线程同步的非原子内存,唯一的内存已经是原子的。
所以没有必要使用比memory_order_relaxed
更重的东西。上面的代码片段是有效的,会产生想要的结果。