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

时间:2015-01-23 15:57:50

标签: c++ c++11 shared-ptr language-lawyer c++14

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

  

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

我不明白我应该如何阅读,以及我应该得出什么结论。 以下是一些解释:

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

对我而言,以上似乎都没有从这句话中得出结论,而我却无法解释它。

3 个答案:

答案 0 :(得分:11)

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

  

为了确定是否存在数据争用,成员函数只访问和修改shared_ptrweak_ptr个对象本身,而不是它们所引用的对象。

这里“他们引用的对象”是指控制块。

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

  

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

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

  

[注意:这是事实,尽管这些功能经常修改use_count() - 结束记录]

答案 1 :(得分:2)

这意味着use_count()中的代码无锁或使用互斥锁来锁定关键部分。换句话说,你可以从线程中调用它而不必担心竞争条件。

答案 2 :(得分:2)

我认为当我们添加上一句话时,意图会变得更加清晰:

  

为了确定是否存在数据争用,成员函数应仅访问和修改shared_ptr和weak_ptr对象本身,而不是它们引用的对象。 use_count()中的更改不反映可能引入数据争用的修改。

所以,最后一句话只是强调与第一句话相同的观点。例如,如果我复制shared_ptr,其使用次数将会增加,以反映shared_ptr已被复制的事实 - 因此use_count()的结果将会更改 - 但这是允许访问(并且,特别是,不允许修改)指针对象,因此它永远不会在使用该指针对象时引入数据争用。