您的位置:首页 > 其它

shared_ptr 智能指针 详解

2015-10-09 11:41 148 查看
感觉网上的内容讲解的都不是太说到点子上,陈硕说的还是非常好的。

shared_ptr: 引用计数智能指针。 与
auto_ptr
的区别是,
shared_ptr
实现时包含一个引用计数(count-ref)。在一个
shared_ptr
对象销毁的时候,会将引用计数减一,直到引用计数为0的时候才真正的会销毁其所指向的对象。

int main(){
shared_ptr<int> sp1(new int(3));
shared_ptr<int> sp2;
sp2 = sp1;   //引用计数会增加1,不会导致所有权的转移。
return 0;    //在函数结束的时候会调用这些局部变量的析构函数,会将引用计数减一,直到引用计数为0.
}


shared_ptr 的内部实现

包括两个部分: T*m_data指向真正的对象; 引用计数的指针(堆上的内存空间的分配)。

(有的人可能会想要采用 static 来实现引用计数,这是不对的)。

VS中 shared_ptr的实现方式,如下图所示:


shared_ptr 线程安全

根据Boost的标准库文档,shared_ptr的线程安全级别 与
内建模型,标准库容器、std::string
一样,即:

一个shared_ptr对象可以被多个线程同时读取

两个 shared_ptr 对象可以被 两个线程同时写入,”析构函数“ 算是写操作。

如果两个 线程需要同时写一个 “shared_ptr”对象,那么需要加锁操作。

请注意,以上是shared_ptr对象本身的线程安全级别,不是它所管理的对象的线程安全级别

以上内容摘自陈硕的博客,讲的很清楚,不过需要时间理解。

两个线程对同一个shared_ptr对象读肯定是线程安全的。

两个
shared_ptr
对象管理同一个对象,并且分别被两个线程操作: 如果只是操作
shared_ptr
对象本身,比如说 给这个对象赋值、调用其析构函数、作为复制构造函数的参数等,那么是线程安全的(因为只会操作引用计数,而引用计数是无锁且安全的)。如果两个线程是同时操作
shared_ptr
所指向的对象,那么是线程不安全的。 因为对其所管理的对象是没有加锁的。

如果同一个
shared_ptr
对象 被两个线程同时访问(写),不是线程安全的。 因为
shared_ptr
对象包括两个部分
引用计数  与  数据指针
。 对这个两个部分的同时访问不是原子操作得。 所以一定不是线程安全得。

shared_ptr
对象的引用计数是无锁其安全的,如何实现无锁且安全的呢? 因为引用计数只是一个
integer 变量
所以可以用
原子变量
来实现。(特殊的机器指令)

shared_ptr 使用技巧

shared_ptr 的 引用计数含有指向 class T的指针的原因?

引用计数是原子类型的原因?

对于 “为什么引用计数需要原子操作?” 的答案。

我的理解是: 因为 shared_ptr 需要保证 “两个shared_ptr对象可以被两个线程同时写入,析构算是写操作,哪怕这两个shared_ptr 管理同一个对象“ 这个线程安全的级别。

具体来说:

shared_ptr<int> sp1(new int(3));   //线程1,执行
shared_ptr<int> sp2 = sp1;         //线程2,执行。


sp1 与 sp2 中都有两个指针,并且指向的地方相同。 指向 new int(3) 这片空间, 指向 引用计数的区间。 当线程1 中的 sp1 析构的时候,引用计数此时会减一,这个时候必须是原子操作,才可以保证正确性。 因为需要达到这个级别的线程安全,所以 引用计

数必须是原子类型的。

参考

[1] 陈硕 http://www.cppblog.com/Solstice/archive/2013/01/28/197597.html

[2] 分析与实现/article/5603650.html

[3] http://en.cppreference.com/w/cpp/memory/shared_ptr

[4] shared_ptr 线程安全分析 /article/9649198.html

[5] 源码剖析 /article/3461991.html

[6] quora https://cppwisdom.quora.com/shared_ptr-is-almost-thread-safe

[7] stackoverflow http://stackoverflow.com/questions/9127816/stdshared-ptr-thread-safety-explained

[8] stackoverflow http://stackoverflow.com/questions/14482830/stdshared-ptr-thread-safety
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: