这段Standardese关于shared_ptr的use_count()的含义是什么?

And*_*owl 26 c++ shared-ptr language-lawyer c++11 c++14

在尝试围绕这个问题中显示的问题时,我发现自己陷入了[util.smartptr.shared]/4中的以下句子:

[...]更改use_count()不反映可能引入数据争用的修改.

我不明白我应该怎么读,以及我应该得出什么结论.以下是一些解释:

  • 调用use_count()不会引入数据争用(但这应该由该const函数的-ness单独保证,以及相应的库范围保证)
  • 返回的值use_count()不受("不反映"?)影响需要原子性或同步的操作的结果(但这些相关操作是什么?)
  • use_count() 以原子方式执行,但不会阻止CPU或编译器重新排序(即没有顺序一致性,但为什么不提及特定模型?)

对我来说,上述任何一个似乎都没有从那句话中得出,而我却在试图解释它.

eca*_*mur 11

当前的措辞来自库问题896,该问题还解决了是否shared_ptr应该是线程安全的问题,即可以shared_ptr同时从不同的线程访问(特别是复制和销毁)拥有相同对象的不同s.该讨论的结论是shared_ptr应该是线程安全的; 保证这一点的机制是假装shared_ptr成员函数只访问shared_ptr对象本身而不是它的堆上控制块:

用于确定数据种族的存在的目的,成员函数访问和修改仅shared_ptrweak_ptr物体本身而不是它们引用的对象.

这里"它们引用的对象"表示控制块.

然而,这提出了一个问题; 如果我们假装shared_ptr拥有相同对象的不同s不访问控制块,那么肯定use_count()无法改变?这是通过制作use_count()一个凭空产生结果的神奇功能来修补的:

更改use_count()不反映可能引入数据争用的修改.

也就是说,use_count()可以从一个调用更改为下一个调用,但这并不意味着发生了数据竞争(或潜在的数据竞争).这可能比该句子以前的措辞更清楚:

[ 注:这是真实的,尽管这一事实,这种功能往往修改use_count()达-注完 ]

  • 我认为可以添加到这个优秀答案的一条信息来自[res.on.data.races]:_"7如果对象对用户不可见并且受到保护,则实现可以在线程之间共享它们自己的内部对象"_这个保证不适用于控制块,因为`use_count()"表示控制块的一部分"对用户可见",因此需要讨论的语句才能指定共享控制块保证线程之间不会引入比赛. (3认同)
  • @AndyProwl很好,可以通过操作来自不同线程的相同`shared_ptr`来引入使用这些操作的数据竞争,但我认为我们在这里是同一页面.关键是可以观察到`use_count()`已发生变化,而这并不意味着发生了数据竞争. (2认同)
  • @curiousguy不,标准使用术语"应该",当应用于实现时,说明实施"必须"做什么.您可以将我使用"控制块"视为"无论内部实现细节用于实现`use_count`"的简写; 效果不变. (2认同)