Jos*_*vin 4 c++ multithreading atomic lockless instruction-reordering
鉴于:
std::atomic<uint64_t> x;
uint64_t f()
{
x.store(20, std::memory_order::memory_order_relaxed);
x.store(10, std::memory_order::memory_order_relaxed);
return x.load(std::memory_order::memory_order_relaxed);
}
Run Code Online (Sandbox Code Playgroud)
假设只有一个线程写入,是否有可能f返回除 之外的值?对于非原子变量来说显然不是这样,但我不知道relaxed是否如此宽松以至于它会忽略同一线程中的数据依赖关系?10x
加载的结果始终是10(假设只有一个线程)。即使是宽松的原子变量也比非原子变量“更强”:
\n宽松的原子变量不能用于使不同的线程彼此同步,除非伴随着显式的栅栏。与适用于原子变量的其他内存顺序相比,这就是它的宽松之处。
\n对于语言律师,请参阅 C++20 [intro.races]/10:
\n\n\n如果满足以下条件,则评估A 发生在评估B之前(或者等效地,B发生在A之后):
\n\n
\n- A在B之前排序,或 [...]
\n
和[介绍.races]/15:
\n\n\n如果修改原子对象M的操作A发生在修改M的操作B之前,则A 的修改顺序应早于B。[注意:此要求称为写入连贯性。\xe2\x80\x94尾注]
\n
和[介绍.races]/18:
\n\n\n如果原子对象M上的副作用X发生在M的值计算B之前,则评估B应从X或按照M的修改顺序从X后面的副作用Y获取其值。[注意:此要求称为写读一致性。\xe2\x80\x94尾注]
\n
因此,在您的程序中,20 的存储发生在 10 的存储之前(因为它在 10 之前排序),并且 10 的存储发生在加载之前。写-写一致性要求保证 10 的存储在修改顺序上x比 20 的存储晚发生。当加载发生时,需要从 10 的存储中取出它的值,因为 10 的存储发生在之前它并且没有其他修改可以遵循 的修改顺序中的 10 存储x。
| 归档时间: |
|
| 查看次数: |
291 次 |
| 最近记录: |