简短介绍:我正在研究多线程代码,我必须在两个线程之间共享动态分配的对象。为了使我的代码更清晰(并且更不容易出错),我想明确地“删除”每个线程中的对象,这就是我想使用shared_ptr
的原因。
第一个问题:
我想知道-> operator
中shared_ptr
的实施是否在运行时期间有一些额外的开销(例如大于unique_ptr
)。我正在谈论的对象通常是在创建后仅复制一次的longlife实例(当我在线程之间分发它们时),然后我只访问这些对象的方法和字段。
我知道,shared_ptr
仅保护引用计数。
第二个问题:
libstdc ++中shared_ptr
的优化程度如何?它总是使用互斥量还是利用原子操作(我专注于x86和ARM平台)?
答案 0 :(得分:14)
第一个问题:使用
operator->
我看到的所有实现都在T*
类中有shared_ptr<T>
的本地缓存,因此该字段位于堆栈中,operator->
因此具有与使用堆栈本地T*
:根本没有开销。
第二个问题:mutex / atomics
我希望libstdc ++在x86平台上使用atomics,无论是通过标准工具还是特定的g ++内在函数(在旧版本中)。我相信Boost实现已经这样做了。
但是,我不能对ARM发表评论。 注意:C ++ 11引入了移动语义,在shared_ptr
的使用中自然避免了许多副本。
注意:请阅读shared_ptr
here的正确用法,您可以使用shared_ptr
(const
或不{{1}})的引用来避免大部分副本/一般的破坏,所以那些表现并不太重要。
答案 1 :(得分:13)
GCC的shared_ptr将在单线程代码中不使用锁定或原子。在多线程代码中,如果CPU支持原子比较和交换指令,它将使用原子操作,否则引用计数受互斥锁保护。在i486及更高版本上它使用原子,i386不支持cmpxchg,因此使用基于互斥锁的实现。我相信ARM使用原子技术用于ARMv7架构以及稍后。
(这同样适用于std::shared_ptr
和std::tr1::shared_ptr
。)