C++的模板(十):shared_ptr的上锁问题

C++STL中的智能指针shared_ptr以前没用过,它是不是线程安全过去也没关注过。很多说它是不安全的,也有说是安全的。线程安全的问题,简单测试是测不出,到底怎么样,需要直接看代码。

从代码看,shared_ptr是个简单包装,真正的代码从__shared_ptr开始。shared_ptr不过是换了个名字,并从__shared_ptr引出构造函数和赋值运算:

  template<typename _Tp>
    class shared_ptr
    : public __shared_ptr<_Tp>
    {
   
   
    };

__shared_ptr含有2个数据元素:

  template<typename _Tp>
    class __shared_ptr {
   
   

      _Tp*         	   _M_ptr;         
      __shared_count<_Lp>  _M_refcount;   
    };

_M_ptr是被__shared_ptr管理的对象指针,_M_refcount又是一个简单包装,内部包含一个指向_Sp_counted_base的指针:

  template<_Lock_policy _Lp = __default_lock_policy>
    class __shared_count
    {
   
   

      _Sp_counted_base<_Lp>*  _M_pi;
    };

这是个多态指针,实际使用时还要扩展一个指针成员:

  template<typename _Ptr, _Lock_policy _Lp>
    class _Sp_counted_ptr
    : public _Sp_counted_base<_Lp>
    {
   
   
      
      _Ptr             _M_ptr;  // .... ........... .... ... .....
    };

这个_M_ptr也是那个被引用计数管理的对象指针,在_Sp_counted_base及其派生类的管理范围内,如果引用计数归0,最后要销毁这个被管理的对象。但回溯到__shared_ptr 类去找到这个_M_ptr,增加了难度,所以这里又保存了一次。反过来看,这里保存的是真本,而__shared_ptr 类保存的是为了优化指针运算符重载而保留的副本。

基础类_Sp_counted_base除了扩展一个指针,根据需要,还可以扩展自定义分配器和清除器。并非所有的对象直接从new出来,有的通过自定义内存管理分配,它们会有自己专用的分配器和清除器:

  template<typename _Ptr, typename _Deleter, typename _Alloc, _Lock_policy _Lp>
    class _Sp_counted_deleter
    : public _Sp_counted_ptr<_Ptr, _Lp>
    {
   
   
      typedef typename _Alloc::template
          rebind<_Sp_counted_deleter>::other _My_alloc_type;

      struct _My_Deleter
      : public _My_alloc_type   
      {
   
   
        _Deleter _M_del; 
        _My_Deleter(_Deleter __d, const _Alloc& __a)
          : _My_alloc_type(__a)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值