【发布时间】:2018-02-19 11:07:42
【问题描述】:
我在尝试实现共享指针时遇到了这个问题。让我们关注托管数据指针。它的生命周期可以分为三个阶段:
- 没有并发访问的构造。
- 并发读取(无写入)。
- 没有并发访问的破坏。这是通过引用计数来保证的。
我的问题是,在这种情况下,指针是否必须是原子的?我认为它相当于:如果指针不是原子的,第 2 阶段会导致未定义的行为吗?理想情况下,我希望听到从理论(语言律师)和实践的角度讨论的答案。例如,如果不是原子的,第 2 阶段理论上可能是未定义的行为,但在实际平台上实际上是可以的。实现共享指针,如果非原子可以,托管指针可以是unique_ptr<T>,否则必须是atomic<T*>。
更新
我找到了标准文本(第 1.10 节 p21):
一个程序的执行包含一个数据竞争,如果它包含两个 不同线程中的冲突操作,至少其中一个不是 原子的,并且两者都不发生在另一个之前。任何此类数据竞赛 导致未定义的行为。
我猜并发读取不会被归类为冲突操作。有人能找到一些关于这个的标准文本来确定吗?
【问题讨论】:
-
您的问题听起来令人困惑,您会更改托管指针本身吗?如果不是,则指针是否为
atomic无关紧要。 -
@liliscent 修改操作发生在没有并发访问的构造和销毁(1 和 3)阶段。并发访问仅发生在只有读访问的第 2 阶段。
-
这也是我的想法。在这种情况下,老实说,我找不到与原子指针的任何联系。原子指针仅在指针本身将被更改时使用,即您的上下文中的“写访问”。
-
@liliscent 我找到了标准文本 "如果一个程序在不同的线程中包含两个冲突的动作,则程序的执行包含数据竞争,其中至少一个不是原子的,并且两者都没有发生任何此类数据竞争都会导致未定义的行为。” 我猜并发读取不会归类为冲突操作?
-
@lingxi:这是您要查找的内容吗:“如果其中一个修改内存位置而另一个访问或修改相同的内存位置,则两个表达式求值会发生冲突。" ?
标签: c++ c++11 concurrency language-lawyer atomic