以下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中的返回值不同。
最佳答案
简短的回答:是的。
长答案:std::memory_order_relaxed
描述为:
Source
这实际上意味着仅保证原子性。这意味着std::atomic::fetch_sub
操作将仅保证原子的read-modify-write操作,而不会对其他操作进行任何排序。但是,这并不意味着编译器可以对两个不同的原子读取,修改和写入操作进行重新排序(这可能导致数据争用,这是未定义的行为)。它们仍然是原子。
在这种情况下,内存顺序无关紧要。它们都不会干扰原子性的基本保证。您所做的上述声明将对任何内存顺序均成立,因为根据定义,该声明对于以这种方式修改的原子变量(从2
的初始值中减去两次,可能是异步的)都适用。
是的,是的,假设线程在x
调用之后返回fetch_sub
持有的值,这从技术上讲可能是错误的(线程不返回值),但是我知道您从这里来了。
关于c++ - 单个变量的原子运算,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59473790/