在没有多线程的情况下,copy-on-write的实现
shared_ptr
(来自 boost 或 tr1)使用 unique()
是
直截了当。多线程时需要做哪些改变?
引用计数是原子的,所以我假设我可以创建、复制构造、
读取和销毁 shared_ptr
的实例而无需进一步担心。
一般而言,特别是在实现时如何更新它们
写时复制?需要锁吗?或者使用 boost::atomic_store
(为什么没有记录)?或者等待一个完整的原子版本
shared_ptr
(不是一个选项)?
编辑:
sfossen,感谢您的有用回复。
所以我得出结论,如果我仅在分离后更改指向的对象
它通过 COW,因此只有当前线程拥有它,不需要锁定
并且 COW 实现看起来就像单线程的
将 shared_ptr 与原子引用计数一起使用时。
最佳答案
使用 COW,您只需要在复制可能正在更改的对象时锁定。
因此,如果对象的 COW,是一个在线程之前设置的对象并且永远不会改变,则不需要锁定。
但是,如果您正在制作拷贝的拷贝,那么您至少需要在初始写入期间锁定,或者确保拷贝在能够再次复制之前进行了所有更改。
如果您不能完全保证这些,则使用锁定或原子更新。
如果你想锁定:
现在主干中确实有一个原子版本。
如果您无法更新 boost,您可以暂时导入所需的函数,或者将其包装在一个锁中,例如读写器锁。
来自 shared_ptr.hpp
template<class T> shared_ptr<T> atomic_exchange( shared_ptr<T> * p, shared_ptr<T> r )
{
boost::detail::spinlock & sp = boost::detail::spinlock_pool<2>::spinlock_for( p );
sp.lock();
p->swap( r );
sp.unlock();
return r; // return std::move( r )
}
关于 RWLocks 的文章
关于c++ - 多线程时使用 shared_ptr 进行写时复制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/616951/