我正在阅读http://gcc.gnu.org/onlinedocs/libstdc++/manual/shared_ptr.html和一些帖子 安全 </跨度> 对我来说问题仍然不明确:
标准保证引用计数是处理线程…线程 安全 </跨度> 对于存储在其中的对象?
编辑:
伪代码:
//线程I的shared_ptr&LT a取代; a(新A(1));
//线程II的shared_ptr&LT a取代; b(a);
//线程III的shared_ptr&LT a取代; c(a);
//线程IVshared_ptr&lt; A …
std :: shared_ptr不是线程安全的。
共享指针是一对两个指针,一个指向对象,一个指向控制块(保持ref计数器,链接到弱指针......)。
可以有多个std :: shared_pointer,每当他们访问控制块来更改引用计数器时它都是线程安全的,但“std :: shared_ptr”本身不是线程安全的或原子的。
如果在另一个线程使用它时将新对象分配给std :: shared_pointer,它可能会以新对象指针结束,但仍然使用指向旧对象的控制块的指针=&gt; CRASH。
正确, shared_ptr s使用引用计数值的原子递增/递减。
shared_ptr
该标准保证只有一个线程将在共享对象上调用delete运算符。我不确定它是否具体指定删除其共享指针副本的最后一个线程将是调用delete的那个(实际上可能就是这种情况)。
不,他们没有,存储在其中的对象可以由多个线程同时编辑。
编辑:稍作后续,如果你想了解共享指针如何工作一般你可能想看看 boost::shared_ptr 资源: http://www.boost.org/doc/libs/1_37_0/boost/shared_ptr.hpp 。
boost::shared_ptr
正如其他人所指出的那样,你已经正确地弄清楚了原来的3个问题。
但是你编辑的结尾部分
在线程IV中调用reset()将删除在第一个线程中创建的A类的先前实例并将其替换为新实例?此外,在IV线程中调用reset()之后,其他线程只会看到新创建的对象?
是不正确的。只要 d 将指向新的 A(10) ,和 a , b ,和 c 将继续指向原文 A(1) 。在以下简短示例中可以清楚地看到这一点。
d
A(10)
a
b
c
A(1)
#include <memory> #include <iostream> using namespace std; struct A { int a; A(int a) : a(a) {} }; int main(int argc, char **argv) { shared_ptr<A> a(new A(1)); shared_ptr<A> b(a), c(a), d(a); cout << "a: " << a->a << "\tb: " << b->a << "\tc: " << c->a << "\td: " << d->a << endl; d.reset(new A(10)); cout << "a: " << a->a << "\tb: " << b->a << "\tc: " << c->a << "\td: " << d->a << endl; return 0; }
(显然,我没有打扰任何线程:这不会影响到 shared_ptr::reset() 行为。)
shared_ptr::reset()
这段代码的输出是
a:1 b:1 c:1 d:1 a:1 b:1 c:1 d:10
a:1 b:1 c:1 d:1
a:1 b:1 c:1 d:10