单个变量的原子运算

时间:2019-12-24 22:19:09

标签: c++ multithreading relaxed-atomics

在以下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中的返回值不同。

1 个答案:

答案 0 :(得分:5)

简短的回答:是的。

长答案:std::memory_order_relaxed被描述为:

  

轻松的操作:没有对其他读写操作施加任何同步或排序约束,只能保证此操作的原子性。

Source

这实际上意味着仅保证原子性。这意味着std::atomic::fetch_sub操作将仅保证原子的read-modify-write操作,而不会对其他操作进行任何排序。但是,这并不意味着编译器可以重新排序两个不同的 atomic 读取,修改和写入操作(这可能导致数据争用,这是未定义的行为)。它们仍然原子

  

理想情况下,我希望x最后为零。即使我正在使用std::memory_order_relaxed,是这样吗?

在这种情况下,内存顺序无关紧要。它们都不会干扰原子性的基本保证。您所做的上述声明在 any 内存顺序中均成立,因为根据定义,该声明适用于以这种方式修改的任何原子变量(从的初始值减去两次,可能是异步的) 2

  

为使问题更精确,是否保证1)在两个线程中的返回值均为01,以及2)在线程1中的返回值和2不同。

是和是,假设线程在x调用之后返回fetch_sub持有的值,这在技术上可能是不正确的(线程不会返回值),但我知道您来自这里。