• Log in
Anwen  Share and Create
  • Book
  • Movies
  • Music
  • SF
  • Goodlink
  • Asks
  • Eyeopen
  • Create

侵入式智能指针 boost::instrusive

Sharer: 阅微堂 January 10, 2020 at 11:00 pm
Link Share :https://zhiqiang.org/coding/boost-instrusive-ptr.html - via RSS

如果理解了侵入式容器,侵入式智能指针也很容易理解。传统的智能指针std::shared_ptr使用了和数据无关的引用计数,这带来两个问题:

  • 引用计数要在shared_ptr对象间共享,所以它只能位于堆上。这使得每次都需要重新new一小块内存。这导致性能问题。
  • 引用计数的内存区域和数据区域不一致,缓存失效导致性能问题。
  • 编写代码不善,将导致同一个数据,绑定到了两个引用计数,从而导致双重删除问题。典型代码如下:

    int* x = new int; std::sharedptr x1 = x; std::sharedptr x2 = x;

侵入式智能指针试图解决这些问题,方法也特别直接,那就是将引用计数直接塞进数据本身,和数据共存亡。从用户角度,这只需要继承boost::instrusive_ptr_base基类:

struct T : public boost::instrusive_ptr_base<T>
{
public:
    int age;
    std::string name;
};

T* t = new T();

// 下面这么些很安全,而且速度很快!
boost::instrusive_ptr<T> x1 =t;
boost::instrusive_ptr<T> x2 =t;

我们看boost::instrusive_ptr_base的定义,其核心就是增加一个原子操作的引用计数,以及自增和自减引用计数的函数:

template<class T>
class boost::intrusive_ptr_base {
public:
    intrusive_ptr_base() : ref_count(0) {}

    friend void intrusive_ptr_add_ref(intrusive_ptr_base<T> const* p) {
        ++p->ref_count;
    }

    friend void intrusive_ptr_release(intrusive_ptr_base<T> const* p) {
        if (--p->ref_count == 0) {
            boost::checked_delete(static_cast<T const*>(s));
        }
    }

    boost::intrusive_ptr<T> self() {
        return boost::intrusive_ptr<T>((T*)this);
    }

private:
    mutable boost::detail::atomic_count ref_count;
};

接下来实际的boost::instrusive_ptr的定义就很简单了:

template<class T> 
class boost::intrusive_ptr {
public:
    intrusive_ptr(T* p, bool add_ref = true) : px(p) {
        if (px != 0 && add_ref) {
            intrusive_ptr_add_ref(px);
        }
    }

    ~intrusive_ptr() {
        if (px != 0) {
            intrusive_ptr_release(px);
        }
    }

private:
    T * px;
}

由于解决了std::shared_ptr的三个问题,boost::instrusive_ptr的效率更高。但它也有缺陷。除了侵入式设计之外,最重要的是boost::instrusive_ptr无法支持weak_ptr,从而无法解决环形引用问题。这时因为std::shared_ptr里的数据对象和计数器分离,可以有不同的生命周期。shared_ptr的引用计数里有两个计数对象,从而支持weak_ptr。

另外一个方面,std::shared_ptr也意识到了其性能问题,内部也提供机制解决这些问题,其核心便是std::make_shared和std::enable_shared_from_this。

参考:C++智能指针 3 :内存布局(非侵入式、enablesharedfrom_this & 侵入式)

作者暂无likerid, 赞赏暂由本网站代持,当作者有likerid后会全部转账给作者(我们会尽力而为)。

Tips: Until now, everytime you want to store your article, we will help you store it in Filecoin network. In the future, you can store it in Filecoin network using your own filecoin.


Support author:
Author's Filecoin address:
Or you can use Likecoin to support author:
tags:编程 C++ Boost 智能指针

0 0

2012-2018 Anwen All of our posts are default licensed under CC BY 4.0 About Help Changelog Telegram
Today Quote: 专制制度下只有两种人:一种是哑子,一种是骗子。我看今天的中国就是少数骗子在统治多数哑子。 -- 王亚南