std::shared_ptr线程安全性已解释
std::shared_ptr thread safety explained
我正在阅读http://gcc.gnu.org/onlinedocs/libstdc++/manual/shared_ptr.html和一些线程安全问题对我来说仍然不清楚:
- 标准保证引用计数是线程安全处理的,并且是独立于平台的,对吧
- 类似的问题-标准保证只有一个线程(持有最后一个引用)会在共享对象上调用delete,对吧
- 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()将删除在第一个线程中创建的A类的前一个实例,并用新实例替换它?此外,在IV线程中调用reset()后,其他线程将只看到新创建的对象?
正如其他人所指出的,关于最初的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;
}
(很明显,我没有为任何线程而烦恼:这并没有考虑到shared_ptr::reset()
行为。)
该代码的输出是
a: 1 b:1 c:1 d:1
a: 1 b:1 c:1 d:10
-
正确,
shared_ptr
使用引用计数值的原子增量/减量。 -
该标准保证只有一个线程会在共享对象上调用delete运算符。我不确定它是否具体指定了删除共享指针副本的最后一个线程将是调用delete的线程(在实践中可能是这样)。
-
不,否则,存储在其中的对象可以由多个线程同时编辑。
编辑:稍微跟进一下,如果你想了解共享指针通常是如何工作的,你可能想看看boost::shared_ptr
来源:https://www.boost.org/doc/libs/release/boost/smart_ptr/shared_ptr.hpp.
std::shared_ptr
不是线程安全的。
共享指针是一对两个指针,一个指向对象,另一个指向控制块(保存ref计数器,链接到弱指针…)。
可以有多个std::shared_ptr,每当它们访问控制块以更改引用计数器时,它都是线程安全的,但std::shared_ptr
本身不是线程安全的或原子的。
如果将一个新对象分配给std::shared_ptr
,而另一个线程正在使用它,那么它可能最终会使用新对象指针,但仍然使用指向旧对象=>CRASH的控制块的指针。
- 请解释"函数1(p1,p2,p3);"的输出
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 被解释为低级别const的const对象的地址
- 类与私有变量的其他类之间的线程安全性
- 计算每个节点的树高,帮助我解释这个代码解决方案
- MSVC将仅移动结构参数解释为指针
- 内联程序集printf将整数解释为地址
- 有人能解释一下为什么下界是这样工作的吗C++的
- Visual Studio(或任何其他工具)能否将地址解释为调用堆栈(boost上下文)的开头
- 我是c ++的新手,你能解释一下在这种情况下的指针吗
- 有人能为我解释一下C++代码吗
- 是否值得降低我的代码的可读性,以便在出现内存不足错误时提供异常安全性?
- 你能解释一下什么运行时错误是如何解决它的吗?
- 请解释字谜的代码,我看不懂计数器数组,每个值已经是0
- 有人可以向我解释为什么控制台输出 0 吗?
- 有人可以解释一下这段代码如何能够反转字符串
- 在 C++ 中解释多维向量的语句时感到困惑
- 将整数解释为字节数组的安全性
- 是从指针的矢量到常量指针的矢量的重新解释强制转换的安全性
- std::shared_ptr线程安全性已解释