【发布时间】:2015-03-27 18:19:49
【问题描述】:
在boost 的shared_ptr 实现中,它使用relaxed memory ordering to increment its reference count。这看起来很安全,因为减量使用获取/释放来确保在释放内存之前线程可以看到任何先前的减量。这个方法似乎是正确的,出现在 Herb Sutters talk on atomics
在 libc++ 的实现中使用full memory barriers
template <class T>
inline T
increment(T& t) _NOEXCEPT
{
return __sync_add_and_fetch(&t, 1);
}
template <class T>
inline T
decrement(T& t) _NOEXCEPT
{
return __sync_add_and_fetch(&t, -1);
}
} // name
这个决定有什么理由吗?它们之间是否有任何性能或安全差异?
【问题讨论】:
-
根据implementation details here,它说“为了满足线程安全要求,引用计数器通常使用等效于 std::atomic::fetch_add 和 std::memory_order_relaxed 来递增和递减。”我希望找到它的来源以确认该声明,但我无法找到 gcc 的 libc++ 源代码的在线文档(尽管它们只是天真的 Google 搜索,也许有人可以提供链接)。我注意到您的链接是针对 LLVM 的。
-
谁编写了该代码,何时,为什么以及他们还编写了什么......如果有办法找出来。 ;)
-
@Aggieboy 我认为我链接的镜像也是 GCC 上 libc++ 的源代码,您只需使用
-gcc-toolchain编译它。 libstd++(GCC 上的默认标准库)使用__gnu_cxx::__exchange_and_add,我相信这也是一个完整的障碍,但我不确定。似乎应该以宽松的障碍来实现它是常识,但我似乎找不到除了 boost 之外的任何库 -
@UlrichEckhardt 我会满足于一些像样的 cmets :P。我只是好奇为什么任何 STL 实现都会违背线程安全引用计数的最佳实践(为了性能),因为它显然有能力使用它(原子在那里,只需使用它们!)。也许他们就是这样做的,但也许更熟悉原子的人可以阐明这样做是否有充分的理由
-
为了不留下任何不好的感觉,@ChrisT,我想(讽刺地)建议你检查相应的版本控制系统。这就是在许多此类系统中可以使用“责备”或“注释”命令的原因。我不确定这个讽刺是否发生过......
标签: c++ boost thread-safety shared-ptr libc++