首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用shared_ptr实现读-复制-更新?

使用shared_ptr实现读-复制-更新?
EN

Stack Overflow用户
提问于 2010-05-13 07:32:22
回答 1查看 2.3K关注 0票数 4

我对用户空间的RCU (读-复制-更新)非常感兴趣,并试图通过tr1::shared_ptr模拟一个,这是代码,虽然我在并发编程方面真的是一个新手,一些专家可以帮我复习一下吗?

其基本思想是,reader调用get_reading_copy()来获取当前受保护数据的指针(假设它是第一代数据,或G1)。写入器调用get_updating_copy()来获取G1的副本(假设它是G2),并且只允许一个写入器进入临界区。更新完成后,编写器调用update()进行交换,并使m_data_ptr指向G2数据。正在进行的读取器和写入器现在持有G1的shared_ptr,读取器或写入器最终将释放G1数据。

任何新的读者都会得到指向G2的指针,而新的写入者会得到G2的副本(假设它是G3)。G1可能还没有发布,因此多代数据可能会共存。

代码语言:javascript
复制
template <typename T>
class rcu_protected
{
public:
    typedef T                                   type;
    typedef const T                             const_type;
    typedef std::tr1::shared_ptr<type>          rcu_pointer;
    typedef std::tr1::shared_ptr<const_type>    rcu_const_pointer;

    rcu_protected() : m_is_writing(0),
                      m_is_swapping(0),
                      m_data_ptr (new type())
    {}

    rcu_const_pointer get_reading_copy ()
    {
        spin_until_eq (m_is_swapping, 0);

        return m_data_ptr;
    }

    rcu_pointer get_updating_copy ()
    {
        spin_until_eq (m_is_swapping, 0);

        while (!CAS (m_is_writing, 0, 1))
        {/* do sleep for back-off when exceeding maximum retry times */}

        rcu_pointer new_data_ptr(new type(*m_data_ptr));

        // as spin_until_eq does not have memory barrier protection,
        // we need to place a read barrier to protect the loading of
        // new_data_ptr not to be re-ordered before its construction
        _ReadBarrier();

        return new_data_ptr;
    }

    void update (rcu_pointer new_data_ptr)
    {
        while (!CAS (m_is_swapping, 0, 1))
        {}

        m_data_ptr.swap (new_data_ptr);

        // as spin_until_eq does not have memory barrier protection,
        // we need to place a write barrier to protect the assignments of
        // m_is_writing/m_is_swapping be re-ordered bofore the swapping
        _WriteBarrier();

        m_is_writing = 0;
        m_is_swapping = 0;
    }

private:
    volatile long m_is_writing;
    volatile long m_is_swapping;
    rcu_pointer m_data_ptr;
};
EN

回答 1

Stack Overflow用户

发布于 2010-11-18 01:38:22

乍一看,我会用一个互斥锁交换spin_until_eq调用和相关的自旋锁。如果临界区中允许多个写入器,那么我将使用信号量。这些并发机制的实现可能依赖于操作系统,因此也应该考虑性能问题;通常,它们比繁忙的等待更好。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2823512

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档