Goo*_*ofy 100 c++ shared-ptr c++11
我正在阅读http://gcc.gnu.org/onlinedocs/libstdc++/manual/shared_ptr.html,我仍然不清楚一些线程安全问题:
编辑:
伪代码:
// 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));
Run Code Online (Sandbox Code Playgroud)
在线程IV中调用reset()将删除在第一个线程中创建的A类的先前实例并将其替换为新实例?此外,在IV线程中调用reset()之后,其他线程只会看到新创建的对象?
Nic*_*rca 85
正如其他人所指出的那样,你已经正确地弄清楚了原来的3个问题.
但是你编辑的结尾部分
在线程IV中调用reset()将删除在第一个线程中创建的A类的先前实例并将其替换为新实例?此外,在IV线程中调用reset()之后,其他线程只会看到新创建的对象?
是不正确的.只有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;
}
Run Code Online (Sandbox Code Playgroud)
(显然,我没有打扰任何线程:这不会影响shared_ptr::reset()行为.)
这段代码的输出是
a:1 b:1 c:1 d:1
a:1 b:1 c:1 d:10
Not*_*ore 34
正确,shared_ptr使用参考计数值的原子递增/递减.
该标准保证只有一个线程将在共享对象上调用delete运算符.我不确定它是否具体指定删除其共享指针副本的最后一个线程将是调用delete的那个(实际上可能就是这种情况).
不,他们没有,存储在其中的对象可以由多个线程同时编辑.
编辑:稍微跟进,如果你想了解共享指针如何工作,你可能想看看boost::shared_ptr源:http://www.boost.org/doc/libs/1_37_0/boost/shared_ptr.hpp.
Lot*_*har 16
std :: shared_ptr不是线程安全的.
共享指针是一对两个指针,一个指向对象,一个指向控制块(保持ref计数器,链接到弱指针......).
可以有多个std :: shared_pointer,每当他们访问控制块来更改引用计数器时它都是线程安全的,但"std :: shared_ptr"本身不是线程安全的或原子的.
如果在另一个线程使用它时将新对象分配给std :: shared_pointer,它可能会以新对象指针结束,但仍然使用指向旧对象=> CRASH的控制块的指针.
| 归档时间: |
|
| 查看次数: |
55066 次 |
| 最近记录: |