我有一个问题boost::shared_ptr
.
有很多线程.
using namespace boost; class CResource { // xxxxxx } class CResourceBase { public: void SetResource(shared_ptrres) { m_Res = res; } shared_ptr GetResource() { return m_Res; } private: shared_ptr m_Res; } CResourceBase base; //---------------------------------------------- // Thread_A: while (true) { //... shared_ptr nowResource = base.GetResource(); nowResource.doSomeThing(); //... } // Thread_B: shared_ptr nowResource; base.SetResource(nowResource); //...
如果Thread_A不关心nowResource
是最新的,那么这部分代码会有问题吗?
我的意思是当Thread_B没有SetResource()
完全,Thread_A得到一个错误的智能点GetResource()
?
线程安全是什么意思?
如果我不关心资源是否是最新的,那么shared_ptr
当程序nowResource
被释放时会崩溃程序还是会破坏问题shared_ptr
?
boost::shared_ptr<>
提供一定程度的线程安全性.引用计数以线程安全方式进行操作(除非您将boost配置为禁用线程支持).
所以你可以复制一下shared_ptr
,并正确维护ref_count.你不能在多个线程中安全地做的是shared_ptr
从多个线程修改实际的对象实例本身(例如从多个线程调用reset()
它).因此,您的使用不安全 - 您正在修改shared_ptr
多个线程中的实际实例 - 您需要拥有自己的保护.
在我的代码中,shared_ptr
通常是按值传递的本地或参数,所以没有问题.从一个线程到另一个线程我通常使用线程安全队列.
当然,这些都不能解决访问指向的对象的线程安全问题shared_ptr
- 这也取决于您.
从boost 文档:
shared_ptr
对象提供与内置类型相同的线程安全级别.阿shared_ptr
由多个线程实例可以是"读"(仅使用常量操作访问)同时进行. 可以通过多个线程同时"写入"(使用诸如或重置的可变操作来访问)不同的shared_ptr
实例operator=
(即使这些实例是副本,并且在下面共享相同的引用计数.)任何其他同时访问都会导致未定义的行为.
所以你的使用并不安全,因为它使用同时读写m_res
.boost文档中的示例3也说明了这一点.
你应该使用单独的互斥守卫访问m_res
中SetResource
/ GetResource
.