在以下C ++代码片段中,变量x
的可能最终结果是什么? (请根据C ++标准所允许的内容而不是不同平台上当前可用的内容进行回答)
// Inside Thread 0
std::atomic<int> x = {2};
// Inside Thread 1
x.fetch_sub(1,std::memory_order_relaxed)
// Inside Thread 2
x.fetch_sub(1,std::memory_order_relaxed)
理想情况下,我希望x
最后为零。即使我正在使用std::memory_order_relaxed
,是这样吗?
编辑: 为了使问题更精确,是否保证 1)在线程1和2中,返回值为0或1,并且 2)线程1和2中的返回值不同。
答案 0 :(得分:5)
简短的回答:是的。
长答案:std::memory_order_relaxed
被描述为:
轻松的操作:没有对其他读写操作施加任何同步或排序约束,只能保证此操作的原子性。
这实际上意味着仅保证原子性。这意味着std::atomic::fetch_sub
操作将仅保证原子的read-modify-write操作,而不会对其他操作进行任何排序。但是,这并不意味着编译器可以重新排序两个不同的 atomic 读取,修改和写入操作(这可能导致数据争用,这是未定义的行为)。它们仍然原子。
理想情况下,我希望
x
最后为零。即使我正在使用std::memory_order_relaxed
,是这样吗?
在这种情况下,内存顺序无关紧要。它们都不会干扰原子性的基本保证。您所做的上述声明在 any 内存顺序中均成立,因为根据定义,该声明适用于以这种方式修改的任何原子变量(从的初始值减去两次,可能是异步的) 2
。
为使问题更精确,是否保证1)在两个线程中的返回值均为
0
或1
,以及2)在线程1
中的返回值和2
不同。
是和是,假设线程在x
调用之后返回fetch_sub
持有的值,这在技术上可能是不正确的(线程不会返回值),但我知道您来自这里。