考虑在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_data
到buffer_view
的引用,则在检查buffer_view::write_ptr
中的引用计数和另一个获取对buffer_data
的引用的线程之间可能会发生争用通过复制buffer_view
,导致数据损坏。
如何修改此示例以确保线程安全? std::shared_ptr
是用于此的正确构造,还是有更有效的方法?
buffer_view::write_ptr
的调用者就地修改现有缓冲区,但如果存在多个引用,则会将缓冲区复制到新缓冲区一个参考。