这段关于 shared_ptr 的 use_count() 的标准语是什么意思?
What is the meaning of this piece of Standardese about shared_ptr's use_count()?
在尝试解决 this question 中显示的问题时,我发现自己陷入了 [util.smartptr.shared]/4 中的以下句子:
[...] Changes in use_count()
do not reflect modifications that can introduce data races.
我不明白我应该如何阅读它,以及我应该得出什么结论。
以下是一些解读:
- 调用
use_count()
不会引入数据竞争(但这应该由该函数的 const
本身以及相应的库范围保证单独保证)
use_count()
返回的值不受("does not reflect"?)需要原子性或同步的操作结果的影响(但这些相关操作是什么?)
use_count()
以原子方式执行,但不会阻止 CPU 或编译器重新排序(即没有顺序一致性,但为什么不提及特定模型?)
对我来说,上面的 none 似乎是从那句话得出的,我在试图解释它时不知所措。
这意味着use_count()
中的代码要么是无锁的,要么是使用互斥锁来锁定临界区。换句话说,您可以从线程中调用它而不必担心竞争条件。
当前的措辞源自库 issue 896,它还解决了 shared_ptr
是否应该是线程安全的问题,因为不同的 shared_ptr
拥有相同的对象可以是同时从不同的线程访问(特别是复制和破坏)。该讨论的结论是 shared_ptr
应该是线程安全的;保证这一点的机制是假装 shared_ptr
成员函数只访问 shared_ptr
对象本身而不是它的堆上控制块:
For purposes of determining the presence of a data race, member functions access and modify only the shared_ptr
and weak_ptr
objects themselves and not objects they refer to.
这里"objects they refer to"表示控制块
然而,这引发了一个问题;如果我们假装拥有相同对象的不同 shared_ptr
不访问控制块,那么肯定 use_count()
不能改变?这是通过使use_count()
成为一个神奇的函数来修补的,它凭空产生一个结果:
Changes in use_count()
do not reflect modifications that can introduce data races.
也就是说,use_count()
可以从一个调用更改为下一个调用,但这并不意味着发生了数据竞争(或潜在的数据竞争)。从该句子的先前措辞来看,这可能更清楚:
[Note: This is true in spite of that fact that such functions often modify use_count() --end note]
我认为当我们添加上一句时,意图变得更加清晰:
For purposes of determining the presence of a data race, member functions shall access and modify only the shared_ptr and weak_ptr objects themselves and not objects they refer to. Changes in use_count() do not reflect modifications that can introduce data races.
所以,最后一句只是强调了与第一句相同的观点。例如,如果我复制 shared_ptr
,它的使用计数将增加以反映 shared_ptr
已被复制的事实——因此 use_count()
的结果将被改变——但这是不允许访问(尤其是不允许修改)pointee对象,所以它永远不会引入数据竞争使用该指针对象。
在尝试解决 this question 中显示的问题时,我发现自己陷入了 [util.smartptr.shared]/4 中的以下句子:
[...] Changes in
use_count()
do not reflect modifications that can introduce data races.
我不明白我应该如何阅读它,以及我应该得出什么结论。 以下是一些解读:
- 调用
use_count()
不会引入数据竞争(但这应该由该函数的const
本身以及相应的库范围保证单独保证) use_count()
返回的值不受("does not reflect"?)需要原子性或同步的操作结果的影响(但这些相关操作是什么?)use_count()
以原子方式执行,但不会阻止 CPU 或编译器重新排序(即没有顺序一致性,但为什么不提及特定模型?)
对我来说,上面的 none 似乎是从那句话得出的,我在试图解释它时不知所措。
这意味着use_count()
中的代码要么是无锁的,要么是使用互斥锁来锁定临界区。换句话说,您可以从线程中调用它而不必担心竞争条件。
当前的措辞源自库 issue 896,它还解决了 shared_ptr
是否应该是线程安全的问题,因为不同的 shared_ptr
拥有相同的对象可以是同时从不同的线程访问(特别是复制和破坏)。该讨论的结论是 shared_ptr
应该是线程安全的;保证这一点的机制是假装 shared_ptr
成员函数只访问 shared_ptr
对象本身而不是它的堆上控制块:
For purposes of determining the presence of a data race, member functions access and modify only the
shared_ptr
andweak_ptr
objects themselves and not objects they refer to.
这里"objects they refer to"表示控制块
然而,这引发了一个问题;如果我们假装拥有相同对象的不同 shared_ptr
不访问控制块,那么肯定 use_count()
不能改变?这是通过使use_count()
成为一个神奇的函数来修补的,它凭空产生一个结果:
Changes in
use_count()
do not reflect modifications that can introduce data races.
也就是说,use_count()
可以从一个调用更改为下一个调用,但这并不意味着发生了数据竞争(或潜在的数据竞争)。从该句子的先前措辞来看,这可能更清楚:
[Note: This is true in spite of that fact that such functions often modify use_count() --end note]
我认为当我们添加上一句时,意图变得更加清晰:
For purposes of determining the presence of a data race, member functions shall access and modify only the shared_ptr and weak_ptr objects themselves and not objects they refer to. Changes in use_count() do not reflect modifications that can introduce data races.
所以,最后一句只是强调了与第一句相同的观点。例如,如果我复制 shared_ptr
,它的使用计数将增加以反映 shared_ptr
已被复制的事实——因此 use_count()
的结果将被改变——但这是不允许访问(尤其是不允许修改)pointee对象,所以它永远不会引入数据竞争使用该指针对象。