c++ - 多线程时使用 shared_ptr 进行写时复制

标签 c++ multithreading boost c++11

在没有多线程的情况下,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/

相关文章:

c++ - void 指针可以指向 lambda 函数吗?

Java 多线程 : Informix 12. 10 - 无法执行物理顺序读取以获取下一行

c# - SQL语句耗时长线程冲突如何解决?

c++ - std::boost::数组列表

c++ - 如何使用 boost 程序选项获取默认参数值?

c++ - 奇怪的递归静态成员函数作为模板函数参数

c++ - 从模板调用类保护方法

java - 同步到要实例化的对象

c++ - 使用 unordered_sets 的 unordered_map

c++ - 程序忽略输入