C ++ 11原子和侵入式共享指针引用计数

时间:2012-04-22 14:21:32

标签: c++ c++11 shared-ptr atomic

我正在编写侵入式共享指针,我正在使用C ++ 11 <atomic>工具作为参考计数器。以下是我的代码的相关片段:

//...
mutable std::atomic<unsigned> count;
//...

void
SharedObject::addReference() const
{
    std::atomic_fetch_add_explicit (&count, 1u,
        std::memory_order_consume);
}

void
SharedObject::removeReference() const
{
    bool destroy;

    destroy = std::atomic_fetch_sub_explicit (&count, 1u,
        std::memory_order_consume) == 1;

    if (destroy)
        delete this;
}

我先从memory_order_acquirememory_order_release开始,但后来我确信memory_order_consume应该足够好。在进一步审议之后,在我看来即使memory_order_relaxed也应该有用。

现在,问题是我是否可以使用memory_order_consume进行操作,还是可以使用较弱的排序(memory_order_relaxed),还是应该使用更严格的排序?

1 个答案:

答案 0 :(得分:20)

void
SharedObject::addReference() const
{
    std::atomic_fetch_add_explicit (&count, 1u, std::memory_order_relaxed);
}

void
SharedObject::removeReference() const
{
    if ( std::atomic_fetch_sub_explicit (&count, 1u, std::memory_order_release) == 1 ) {
         std::atomic_thread_fence(boost::memory_order_acquire);
         delete this;
    }
}

您希望使用atomic_thread_fencedelete严格地位于fetch_sub之后。 Reference

来自链接文字的引用:

  

始终可以使用增加引用计数器   memory_order_relaxed:只能形成对对象的新引用   从现有引用,并从一个引用现有引用   线程到另一个必须已经提供任何所需的同步。

     

在一个对象中强制执行对对象的任何可能访问非常重要   线程(通过现有引用)在删除之前发生   对象在不同的​​线程中。这是通过“释放”实现的   删除引用后的操作(通过对对象的任何访问)   这个参考必须明显发生在之前),并且“获得”   删除对象之前的操作。

     

可以将memory_order_acq_rel用于fetch_sub   操作,但这导致不需要的“获取”操作时   参考计数器尚未达到零并且可能会产生性能   罚。