std::atomic<bool>执行保证?

std::atomic<bool> execution guarantee?

我知道 std::atomics 应该有明确定义的行为,但我找不到这个问题的易于理解的在线答案:做 std::atomic.load() 和 . store() 有执行保证吗?

如果两个线程尝试对同一个 std::atomic 对象进行并发写入或读取,是否保证写入和读取都被执行?换句话说,是否有可能写入或读取任务根本无法完成?一个或两个会被阻止吗?还是保证它们是按顺序排列的?我不是在这里询问操作顺序。我只是问是否会在未来某个未指定的时间完成手术。

编译器和处理器确保执行编程操作是一个基本假设。这与std::atomic<>无关。 std::atomic<> 提供的保证是单个操作自动发生。

那是什么意思?

考虑两个线程 A 和 B,它们都递增相同的整数变量。此操作通常涉及读取整数、加 1 和写入结果(请注意,这只是一个示例,C++ 标准没有说明操作如何分解为原子步骤,因此我们不能根据标准)。

在这种情况下,我们会有“读取”、“加一”和“写入”步骤。对于每个线程,这些步骤都保证按顺序执行,但不能保证这些步骤是如何交错的。可能是:

   B: read
   B: add1
   B: write
   A: read
   A: add1
   A: write

这导致整数递增两次。

也可以

   A: read
   A: add1
   B: read
   B: add1
   B: write
   A: write

这将导致整数仅递增一次。

因此这个实现会有一个 race condition.

为了摆脱它,我们可以使用 std::atomic<int> 而不是普通的 int 作为整数。 std::atomic<int> 实现了 ++ 运算符,std::atomic<> 提供的保证是在这种情况下递增将自动发生。

在该示例中,这意味着步骤序列 - 读取、加一、写入 - 不会被另一个线程中断。仍然无法保证线程之间的执行顺序。因此,我们可以

   A: read
   A: add1
   A: write
   B: read
   B: add1
   B: write

   B: read
   B: add1
   B: write
   A: read
   A: add1
   A: write

但其他组合是不可能的,在这两种情况下整数都会递增两次。因此没有竞争条件。