有人知道完全线程安全的shared_ptr实现吗?例如,boost实现shared_ptr对于目标(引用计数)是线程安全的,并且对于同时shared_ptr实例读取也是安全的,但不是写入或读/写.
(参见Boost docs,例3,4和5).
是否存在对shared_ptr实例完全线程安全的shared_ptr实现?
提升文档的人说:
shared_ptr对象提供与内置类型相同的线程安全级别.
但是如果你比较一个普通的指针(内置类型)smart_ptr,那么同时写一个普通的指针是线程安全的,但同时写入a smart_ptr不是.
编辑:我的意思是x86架构上的无锁实现.
EDIT2:这种智能指针的一个示例用例是有许多工作线程,它们使用当前工作项更新全局shared_ptr,并使用监视器线程获取工作项的随机样本.shared-ptr将拥有该工作项,直到为其分配了另一个工作项指针(从而销毁了以前的工作项).监视器将获得工作项的所有权(从而防止工作项被销毁),方法是将其分配给自己的shared-ptr.它可以通过XCHG和手动删除来完成,但如果共享ptr可以做到这一点会很好.
另一个例子是全局shared-ptr拥有"处理器",由某个线程分配,并由其他一些线程使用.当"用户"线程看到处理器shard-ptr为NULL时,它使用一些替代逻辑来进行处理.如果它不是NULL,它会通过将处理器分配给它自己的shared-ptr来防止处理器被破坏.
tr1::shared_ptr和之间有什么区别boost::shared_ptr吗?如果是这样,什么?
我可能需要更多地重新考虑我的整体设计,但就目前而言,看起来我可能想做类似的事情:
class A;
class B;
std::map<boost::shared_ptr<const A>, B> APtrToBMap;
Run Code Online (Sandbox Code Playgroud)
我试过这个,它似乎在一个简单的情况下工作(编译器没有抱怨,简单的测试似乎工作).但我对这种方法有了第二个想法.我怀疑那里有一些我不知道的陷阱.
那么,上述实际意义上的有效吗?或者,当我这样做时,我不知道有什么缺陷吗?
在阅读"超越C++标准库:Boost简介"时,我得到了一个非常有趣的例子:
class A
{
public:
virtual void sing()=0;
protected:
virtual ~A() {};
};
class B : public A
{
public:
virtual void sing( )
{
std::cout << "Do re mi fa so la"<<std::endl;;
}
};
Run Code Online (Sandbox Code Playgroud)
我做了一些测试:
int main()
{
//1
std::auto_ptr<A> a(new B); //will not compile ,error: ‘virtual A::~A()’ is protected
//2
A *pa = new B;
delete pa; //will not compile ,error: ‘virtual A::~A()’ is protected
delete (dynamic_cast<B*>(pa)); //ok
//3
boost::shared_ptr<A> a(new B);//ok
}
Run Code Online (Sandbox Code Playgroud)
我在这里很好奇的是~hared_ptr是如何工作的?它如何推导派生类B?
谢谢你的帮助!
谢谢大家,我写了一个关于~share_ptr如何工作的简单示例
class sp_counted_base …Run Code Online (Sandbox Code Playgroud) 我试图比较原始指针,boost shared_ptr和boost weak_ptr之间的性能.在解除引用部分,我期望shared_ptr和raw_ptr相等,但结果显示shared_ptr大约慢两倍.对于测试,我创建一个数组,其中包含指针或指向int的共享指针,然后在循环中取消引用,如下所示:
int result;
for(int i = 0; i != 100; ++i)
{
for(int i = 0; i != SIZE; ++i)
result += *array[i];
}
Run Code Online (Sandbox Code Playgroud)
测试的完整代码可以在这里找到:https: //github.com/coolfluid/coolfluid3/blob/master/test/common/utest-ptr-benchmark.cpp
可以在此处找到没有断言的优化构建的测试时间:http://coolfluidsrv.vki.ac.be/cdash/testDetails.php? test = 145592&build = 7777
感兴趣的值是"DerefShared time"和"DerefRaw time"
我猜测试可能会有某种方面的缺陷,但我没有弄清楚差异来自哪里.分析显示来自shared_ptr的operator*内联,它似乎需要更多时间.我仔细检查了升压断言是否已关闭.
如果有人能解释可能产生的差异,我将非常感激.
其他独立测试:https: //gist.github.com/1335014
简短介绍:我正在研究多线程代码,我必须在两个线程之间共享动态分配的对象.为了使我的代码更清晰(并且更不容易出错),我希望在每个线程中明确地"删除"对象,这就是我想要使用的原因shared_ptr.
第一个问题:
我想知道在运行时是否实现-> operatorin shared_ptr有一些额外的开销(例如更大unique_ptr).我正在谈论的对象通常是在创建之后仅复制一次的longlife实例(当我在线程之间分发它们时),然后我只访问这些对象的方法和字段.
我知道,shared_ptr这只保护引用计数.
第二个问题:
shared_ptr在libstdc ++中如何优化?它总是使用互斥量还是利用原子操作(我专注于x86和ARM平台)?
我在使用boost enable_shared_from_this和多重继承时遇到了一些麻烦.
该场景可以描述如下:
类A实现了一些功能,应该继承enable_shared_from_this
类B实现了另一个功能,应该继承enable_shared_from_this
类D从A和B(class D : public A, public B {})继承功能
当我B从类中使用一些类功能时,D我得到了一个异常(bad_weak_ptr)
继承enable_shared_from_this课程D对我来说不是一个选择
我不知道如何解决这个问题.
哦,我正在使用Visual C++ 2010.
我有以下代码:
void MyClass::onOpenModalBtnClicked() {
uiManager->load(L"data/ui/testmodal.json");
std::shared_ptr<UIElement> modal = uiManager->getElementById("loginModal");
if(modal) {
modal->getElementById("closeButton")->onClicked = [modal]() {
modal->hide();
};
}
}
Run Code Online (Sandbox Code Playgroud)
这个工作正常,点击按钮时模态关闭,onClicked是std::function.
我的应用程序开头也有这个:
#if defined(DEBUG) | defined (_DEBUG)
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endif
Run Code Online (Sandbox Code Playgroud)
这会在应用程序终止时打印出内存泄漏.
使用上面的代码我得到了很多内存泄漏,如果我将代码更改为以下代码,它们都会消失:
void MyClass::onOpenModalBtnClicked() {
uiManager->load(L"data/ui/testmodal.json");
std::shared_ptr<UIElement> modal = uiManager->getElementById("loginModal");
if(modal) {
modal->getElementById("closeButton")->onClicked = [this]() {
uiManager->getElementById("loginModal")->hide();
};
}
}
Run Code Online (Sandbox Code Playgroud)
我假设传递in shared_ptr值会使ref计数增加1,然后这个引用永远不会超出范围,或者在报告mem泄漏后它超出范围.所以我在使用shared_ptr之后尝试在lambda中调用reset但是后来我得到了这个编译错误:
Error 1 error C2662: 'void std::shared_ptr<_Ty>::reset(void) throw()' : cannot convert 'this' pointer from 'const std::shared_ptr<_Ty>' to 'std::shared_ptr<_Ty> &'
所以问题是如何使用捕获modal而不是那些内存泄漏?
编辑: 所以我通过添加 …
我只是在学习智能指针,而且我无法将预先存在的变量位置分配给标准库的共享指针.
例如,假设你有一个int x,你不知道它的值.有了正常的指针,我就是这么做的
int* ptr;
ptr = &x;
Run Code Online (Sandbox Code Playgroud)
我用共享指针尝试了这两个,并且
std::tr1::shared_ptr<int> ptr;
ptr = std::make_shared<int> (&x)
Run Code Online (Sandbox Code Playgroud)
所以我很失落如何做到这一点.
我有两个A和B类,B继承自A.
如果我有一个shared_ptr<A>我知道的对象实际上是B子类型,我怎样才能执行动态转换来访问B的API(请记住我的对象是shared_ptr,而不仅仅是A?
c++ ×10
shared-ptr ×10
boost ×4
tr1 ×2
c++11 ×1
dynamic-cast ×1
lambda ×1
polymorphism ×1
std ×1
stdmap ×1