非原子变量的并发读取

Lin*_*gxi 5 c++ concurrency atomic language-lawyer c++11

我在尝试实现共享指针时遇到了这个问题。让我们关注托管数据指针。它的生命周期可以分为三个阶段:

  1. 没有并发访问的构造。
  2. 并发读取(无写入)。
  3. 没有并发访问的销毁。这是通过引用计数来保证的。

我的问题是,鉴于这种情况,指针是否必须是原子的?我认为这相当于:如果指针不是原子的,阶段 2 会导致未定义的行为吗?理想情况下,我希望听到从理论(语言律师)角度和实践角度进行讨论的答案。例如,如果不是原子的,阶段 2 理论上可能是未定义的行为,但在实际平台上实际上是可以的。为了实现共享指针,如果非原子性可以,托管指针可以是unique_ptr<T>,否则必须是atomic<T*>

更新

我找到了标准文本(第 1.10 节 p21):

如果一个程序在不同的线程中包含两个相互冲突的动作,那么它的执行就包含数据竞争,其中至少一个不是原子的,并且都不在另一个之前发生。任何此类数据竞争都会导致未定义的行为。

我猜并发读取不会归类为冲突操作。有人能找到一些关于这个的标准文本来确定吗?

Ben*_*igt 4

对任何变量的并发读取,无论是否是原子的,都不构成数据竞争,因为冲突评估的定义见[intro.multithread]

如果两个表达式求值之一修改内存位置,而另一个表达式求值访问或修改同一内存位置,则两个表达式求值会发生冲突。

最近,措辞发生了[intro.races]非常微妙的变化

如果两个表达式求值之一修改内存位置,而另一个表达式求值读取或修改同一内存位置,则两个表达式求值会发生冲突。

从访问读取的更改发生在草案 n4296 和 n4431 之间。多线程部分的分割发生在 n4582 和 n4604 之间。