【发布时间】:2014-09-01 04:14:32
【问题描述】:
我想知道使用 shared_ptr 是否安全。请原谅我的伪代码:
Thread 1:
do lock
ReadOnlyObj obj = make_shared<ReadOnlyObj>();
some_shared_ptr.swap(obj);
do unlock
Thread 2-N:
//no lock
some_shared_ptr->getterOnObj();
CPP 参考说
所有成员函数(包括复制构造函数和复制赋值)都可以由多个线程在 shared_ptr 的不同实例上调用而无需额外同步,即使这些实例是副本并共享同一对象的所有权。如果多个执行线程在没有同步的情况下访问同一个 shared_ptr 并且其中任何一个访问使用 shared_ptr 的非常量成员函数,则将发生数据竞争,可以使用原子函数的 shared_ptr 重载来防止数据竞赛。
但是,根据GNU docs:
Boost shared_ptr(在 GCC 中使用)具有巧妙的无锁算法来避免竞争条件,但这依赖于支持原子比较和交换指令的处理器。对于其他平台,有使用互斥锁的回退。 Boost(从 1.35 版开始)包括几种不同的实现,预处理器根据编译器、标准库、平台等选择一个。对于 libstdc++ 中 shared_ptr 的版本,编译器和库是固定的,这使得事情变得更加简单:我们有一个atomic CAS 或者我们没有,请参阅下面的锁定策略了解详细信息。
据我所知,intel x86_64 支持 CAS。
所以,对于我的问题:
shared_ptr::swap 是非常量的。 get 和 ->() 是常量。鉴于上面列出的使用场景,我是否也必须锁定 get/->?
【问题讨论】:
标签: c++ multithreading boost concurrency