Zet*_*eta 6 c++ multithreading synchronization atomic
如果使用单个原子变量 and std::memory_order_seq_cst,是否保证非原子操作不会被重新排序?
例如,如果我有
std::atomic<bool> quux = {false};
void foo() {
bar();
quux.store(true, std::memory_order_seq_cst);
moo();
}
Run Code Online (Sandbox Code Playgroud)
在bar()保证不会得到调用后重新排序store,而moo()不是得到的调用之前重新排序store,只要我使用std::memory_order_seq_cst来自另一个线程的角度看,至少有?
或者,把它放在代码中,如果从另一个线程运行,以下假设是否有效?
if(quux.load(std::memory_order_seq_cst) == true) {
// bar guaranteed to be called; its side-effects are visible
// moo might have been called, but is not guaranteed to
} else {
// bar might have been called, but is not guaranteed to
// moo might have been called, but is not guaranteed to
}
Run Code Online (Sandbox Code Playgroud)
请注意,我假设既不使用bar也不moo使用原子操作、互斥锁、锁、栅栏或其他同步功能。
如果使用单个原子变量 和
std::memory_order_seq_cst,非原子操作是否保证不会被重新排序?
标准在这个http://en.cppreference.com/w/cpp/atomic/memory_order上非常清楚:
memory_order_seq_cst具有此内存顺序的加载操作执行获取操作,存储执行释放操作,读取-修改-写入执行获取操作和释放操作,并且存在一个总顺序,其中所有线程都观察到内存中的所有修改。相同的顺序。
memory_order_acquire使用此内存顺序的加载操作在受影响的内存位置上执行获取操作:在此加载之前,当前线程中的任何读取或写入都不能重新排序。
memory_order_release具有此内存顺序的存储操作执行释放操作:在该存储之后,当前线程中的任何读取或写入都不能重新排序。
换句话说,不能围绕memory_order_seq_cst操作重新排序任何加载或存储(非原子和原子)。
保证
bar()在调用 store 之后不会重新排序,并且moo()在调用 store 之前不会重新排序,只要我使用 std::memory_order_seq_cst ,至少从另一个线程的角度来看?
bar如果和的定义moo在当前翻译单元中不可用,则编译器假定这些函数会加载内存和/或具有副作用(执行 I/O 或存储到内存),因此无法围绕操作重新排序memory_order_seq_cst。
如果定义可用并且函数不执行 I/O 或内存加载/存储,则可以对它们重新排序。这些将是纯函数或不执行任何操作并返回void常量的函数。