std :: shared_ptr内部,弱项超过预期

use*_*229 5 c++ stl shared-ptr

在Advanced STL系列的一(35:00)中,Stephan T Lavavej显示,_Weaks值为0的计数器确定何时删除_Ref_count结构,等于还活着的数量,weak_ptr如果有活着,则加1 shared_ptrs。他解释说,出于线程安全性的考虑,这是必要的:如果_Weaks仅等于weak_ptrthen 的数量,则当last weak_ptr超出范围时,还必须检查_Usesalive shared_ptr的计数器,以检查是否_Ref_count可以删除。由于缺乏原子性,这是不可接受的。

假设_Uses=存活数shared_ptrs _Weaks=存活数weak_ptrs,假设我们有以下情形:

  • _Uses= 0,_Weaks= 1):最后weak_ptr超出范围,递减_Weaks

  • _Uses= 0,_Weaks= 0):如果_Uses等于0,则删除_Ref_count结构

在多线程应用程序中会发生什么错误,从而迫使我们使用_Weak=存活weak_ptr数量+(shared_ptr1:0的数量)实现?

Rei*_*ica 6

想象一下下面的场景。线程A持有a shared_ptr,线程B持有对应的weak_ptr。所以在你的实现中,我们有_Uses == 1_Weaks == 1

智能指针析构函数有两种可能的实现,都存在问题。

实现1:递减,然后检查

weak_ptr被破坏。递减_Weaks。我们有_Uses == 1_Weaks == 0B准备检查_Uses,但是……

上下文切换。

一个shared_ptr被破坏。递减_Uses。我们有_Uses == 0_Weaks == 0。开始销毁_Ref_count.

上下文切换。

B现在开始检查_Uses。它是 0。开始销毁_Ref_count

两个线程现在都在销毁_Ref_count. 不好。

实现2:检查,然后递减

weak_ptr被破坏。检查_Uses。它是 1,不会发生破坏。B准备递减_Weaks,但是...

上下文开关。

一个shared_ptr被破坏。检查_Weaks。它是 1,不会发生破坏。递减_Uses。我们有_Uses == 0_Weaks == 1。完毕。

上下文切换。

B现在轮到 decrement _Weaks。我们有_Uses == 0_Weaks == 0。没有别的事可做。

我们泄露了_Ref_count. 不好。