对共享阵列进行写时复制修改

时间:2015-09-03 18:07:41

标签: c++ multithreading shared-ptr

考虑在N个线程之间共享的只读缓冲区。为了修改缓冲区,请求者确定缓冲区中存在的引用数,并将其复制或就地修改。在单线程模型中,此代码可以编写如下。

class buffer_data;

class buffer_view {
    std::shared_ptr<buffer_data> m_ptr;
public:
    const buffer_data *read_ptr() const
    {
        return m_ptr.get();
    }

    buffer_data *try_write_ptr()
    {
        return m_ptr.unique() ? m_ptr.get() : nullptr;
    }

    buffer_data *write_ptr()
    {
        if (!m_ptr.unique())
            m_ptr = std::make_shared<buffer_data>{ *m_ptr };
        return m_ptr.get();
    }
}

但是,如果多个线程持有buffer_databuffer_view的引用,则在检查buffer_view::write_ptr中的引用计数和另一个获取对buffer_data的引用的线程之间可能会发生争用通过复制buffer_view,导致数据损坏。

如何修改此示例以确保线程安全? std::shared_ptr是用于此的正确构造,还是有更有效的方法?

编辑:buffer_view所需的所有权语义是,如果只存在一个引用,则buffer_view::write_ptr的调用者就地修改现有缓冲区,但如果存在多个引用,则会将缓冲区复制到新缓冲区一个参考。

0 个答案:

没有答案