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

时间:2009-03-05 22:28:37

标签: c++ multithreading boost c++11

在没有多线程的情况下,执行copy-on-write for 使用shared_ptr的{​​{1}}(来自boost或tr1)是 直截了当。多线程需要进行哪些更改? 引用计数是原子的所以我假设我可以创建,复制构造, 阅读并销毁unique()的实例,无需进一步关注。 一般而言,特别是在实施时,如何更新它们 写入时复制?需要锁吗?或者使用shared_ptr (为什么没有记录)?或等待完全原子版的 boost::atomic_store(不是选项)?

编辑:
sfossen,谢谢你的回复 所以我得出结论,如果我在分离后才更改指向对象 它通过COW,只有当前线程拥有它,不需要锁定 而COW实现看起来就像单线程一样 使用带有原子引用计数的shared_ptr时。

2 个答案:

答案 0 :(得分:6)

使用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

上的文章

答案 1 :(得分:0)

在没有某种形式的同步的情况下复制shared_ptr是不安全的,除非它由执行复制的线程拥有。线程安全保证仅适用于由线程拥有的shared_ptr,其中shared_ptr的内部引用计数可由其他线程拥有的shared_ptr共享。

你想要的行为是我调用原子线程安全的,它在shared_ptr中当前不存在,甚至可能在C ++ 0x之后也不会。名称shared_ptr在这里可能有点令人困惑,因为你不能在没有同步的情况下在线程之间共享一个shared_ptr。