std :: shared_ptr线程安全解释
我正在阅读http://gcc.gnu.org/onlinedocs/libstdc++/manual/shared_ptr.html和一些线程安全问题仍然不清楚:
- 标准保证引用计数处理线程安全,它是平台独立的,对吗?
- 类似的问题 – 标准保证只有一个线程(持有最后的引用)将调用共享对象上的删除,对不对?
- shared_ptr不保证存储在其中的对象的任何线程安全?
编辑:
伪代码:
// Thread I shared_ptr<A> a (new A (1)); // Thread II shared_ptr<A> b (a); // Thread III shared_ptr<A> c (a); // Thread IV shared_ptr<A> d (a); d.reset (new A (10));
在线程IV中调用reset()将删除在第一个线程中创build的A类的前一个实例,并将其replace为新的实例? 而且在IV线程中调用reset()之后,其他线程只会看到新创build的对象?
正如其他人指出的那样,你已经正确地解决了你原来的三个问题。
但是编辑的结尾部分
在线程IV中调用reset()将删除在第一个线程中创build的A类的前一个实例,并将其replace为新的实例? 而且在IV线程中调用reset()之后,其他线程只会看到新创build的对象?
是不正确的。 只有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()
行为)。
这个代码的输出是
a:1 b:1 c:1 d:1
a:1 b:1 c:1 d:10
-
正确的,
shared_ptr
使用引用计数值的primefaces增量/减量。 -
标准保证只有一个线程会调用共享对象上的删除操作符。 我不知道是否它具体指定删除其共享指针副本的最后一个线程将调用删除(可能在实践中,这将是这种情况)。
-
不是,存储在其中的对象可以被多个线程同时编辑。
编辑:稍后续,如果你想知道共享指针如何工作一般你可能想看看boost::shared_ptr
来源: http : //www.boost.org/doc/libs/1_37_0/boost/ shared_ptr.hpp 。
std :: shared_ptr不是线程安全的。
共享指针是一对两个指针,一个指向对象,另一个指向一个控制块(持有ref计数器等等)。
可以有多个std :: shared_pointer,并且只要他们访问控制块就是线程安全的,但是“std :: shared_ptr”本身不是线程安全的或者是primefaces的。
如果在另一个指针使用它的同时将一个新对象分配给一个std :: shared_pointer,它可能会以新对象指针结束,但仍旧使用指向旧对象控制块的指针=> CRASH。