通常声称取消引用智能指针不会对性能产生显着影响。 (例如:C Smart Pointer Performance)
我现在想知道这是否真的如此。我理解,如果引用的对象上的操作是原子的,那可能是。
考虑基于此片段的代码:
class Worker
{
[...]
public:
void setDataProvider( shared_ptr<DataProvider> p )
{
m_provider = p;
}
void doWork()
{
[...]
for(;;) {
int d = m_provider->getSomeData();
[ do something with d ]
}
}
private:
shared_ptr<DataProvider> m_provider;
};
doWork()
将被永久执行,并且不时会从第二个线程调用setDataProvider()
。相当普通的智能指针使用场景。
普遍共识认为setDataProvider()
有一些额外费用,因为必须更改受锁保护的引用计数,但m_provider->getSomeData()
还没有。据说它与普通指针解除引用相当,至少不需要昂贵的锁定。
但这怎么可行呢?让我们假设,getSomeData()
不是原子操作,它可能有一些逻辑和显着的执行时间。
*m_provider
执行时如何保护getSomeData()
不被删除?该类可能是该对象的唯一所有者。覆盖m_provider
会将指针的引用值降低一。 m_provider->getSomeData()
暂时必须提高引用计数,否则保护对象不被删除,否则getSomeData()
运行。
在这两种情况下都需要一些昂贵的同步/锁定机制。
附录:我在示例中使用了标准shared_ptr
,因为我一般都在想这个。但实际代码使用QSharedPointer
,所以我对此特别感兴趣。我天真地认为两者都具有相同的线程安全性,这可能是错误的。