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

wil*_*ilx 18 c++ atomic shared-ptr c++11

我正在编写侵入式共享指针,我正在使用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;
}
Run Code Online (Sandbox Code Playgroud)

我已经开始memory_order_acquirememory_order_release第一次,但后来我说服自己memory_order_consume应该足够好.在进一步审议后,在我看来,即使memory_order_relaxed应该工作.

现在,问题是我是否可以memory_order_consume用于操作或者我可以使用较弱的订单(memory_order_relaxed)还是应该使用更严格的订购?

use*_*2k5 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

你想使用atomic_thread_fencedelete是严格的后fetch_sub.参考

从链接文字引用:

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

在删除不同线程中的对象之前,必须在一个线程(通过现有引用)中强制执行对对象的任何可能访问.这是通过在删除引用之后的"释放"操作(通过此引用对对象的任何访问必须明显发生之前)和在删除对象之前的"获取"操作来实现的.

可以将memory_order_acq_rel用于fetch_sub操作,但是当引用计数器尚未达到零时,这会导致不需要的"获取"操作,并且可能会造成性能损失.