14

简短介绍:我正在处理多线程代码,我必须在两个线程之间共享动态分配的对象。为了使我的代码更清晰(并且不易出错),我想在每个线程中显式“删除”对象,这就是我想使用shared_ptr.

第一个问题:

我想知道 in 的实现-> operator在运行时shared_ptr是否有一些额外的开销(例如大于 then unique_ptr)。我正在谈论的对象通常是在创建后仅复制一次的长寿命实例(当我在线程之间分配它们时),然后我只访问这些对象的方法和字段。

我知道,shared_ptr这只保护引用计数。

第二个问题:

shared_ptrlibstdc++的优化程度如何?它总是使用互斥锁还是利用原子操作(我专注于 x86 和 ARM 平台)?

4

2 回答 2

14

第一个问题:使用operator->

我见过的所有实现T*shared_ptr<T>类中都有一个本地缓存,因此该字段在堆栈上,operator->因此与使用堆栈本地的成本相当T*:根本没有开销。

第二个问题:互斥体/原子

我希望 libstdc++ 在 x86 平台上使用原子,无论是通过标准设施还是特定的 g++ 内在函数(在旧版本中)。我相信 Boost 实施已经这样做了。

但是,我不能对 ARM 发表评论。

注意:C++11 引入移动语义,在使用shared_ptr.

注意:阅读有关shared_ptr 此处的正确用法,您可以使用对shared_ptrconst或不)的引用来避免大多数复制/破坏,因此它们的性能并不太重要。

于 2012-06-05T20:02:37.373 回答
13

GCC 的 shared_ptr 将在单线程代码中不使用锁定或原子。在多线程代码中,如果 CPU 支持原子比较和交换指令,它将使用原子操作,否则引用计数受互斥体保护。在 i486 和更高版本上它使用原子,i386 不支持 cmpxchg 因此使用基于互斥锁的实现。我相信 ARM 将原子用于 ARMv7 架构及更高版本。

(这同样适用于std::shared_ptrstd::tr1::shared_ptr。)

于 2012-06-06T14:42:46.147 回答