我正在编写侵入式共享指针并且我正在使用 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_acquire
开始和 memory_order_release
首先但后来我说服自己 memory_order_consume
应该足够好。经过进一步考虑,在我看来,甚至 memory_order_relaxed
应该可以。
现在的问题是我是否可以使用 memory_order_consume
对于操作,或者我可以使用较弱的排序 (memory_order_relaxed
) 还是应该使用更严格的排序?
最佳答案
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_fence
使得 delete
严格在 fetch_sub
之后。 Reference
引用链接文本:
Increasing the reference counter can always be done with memory_order_relaxed: New references to an object can only be formed from an existing reference, and passing an existing reference from one thread to another must already provide any required synchronization.
It is important to enforce any possible access to the object in one thread (through an existing reference) to happen before deleting the object in a different thread. This is achieved by a "release" operation after dropping a reference (any access to the object through this reference must obviously happened before), and an "acquire" operation before deleting the object.
It would be possible to use memory_order_acq_rel for the fetch_sub operation, but this results in unneeded "acquire" operations when the reference counter does not yet reach zero and may impose a performance penalty.
关于C++11 原子和侵入式共享指针引用计数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10268737/