【问题标题】:Why there need memory order limit on reference counter?为什么引用计数器需要内存顺序限制?
【发布时间】:2014-08-14 09:06:38
【问题描述】:

boost::atomic的例子中,unref函数:

void intrusive_ptr_release(const X * x)
{
  if (x->refcount_.fetch_sub(1, boost::memory_order_release) == 1) {
    boost::atomic_thread_fence(boost::memory_order_acquire);
    delete x;
  }
}

1:fetch_sub 操作受 memory_order_release 的限制,这可以防止之前的操作在该点之后重新排序。但是有哪些可能的场景会出现这种现象呢?

2:原子操作上除了memory_order_release外,为什么在删除前还有一个memory_order_acquire

【问题讨论】:

标签: c++ boost atomic memory-model refcounting


【解决方案1】:

对于第一个问题,它防止在fetch_sub 之后重新排序(*x) 的任何使用(当引用计数可能为0 并因此禁止使用时)。可能的原因是 CPU 重新排序或编译器重新排序。第二个问题只是发布的镜像; release 保护存储,acquire 保护负载。

refcount_fetch_sub(1, memory_order_acq_rel) 似乎也可以正常工作,但这只是保护引用计数。

【讨论】:

  • 我知道编译器和 CPU 都可以重新排序命令。但是,在这种情况下,delete x 命令取决于fetch_sub 的结果。为什么delete x 中的内容仍有可能在fetch_sub 之前重新排序?
  • 在单线程视图中,读取可以在不相关的写入之前重新排序,即如果分支成功,x 的其他成员可能已经被读取以防止管道停止。当另一个线程更新x时,这反过来可能会导致删除旧版本的x
  • "但这只是保护 refcount。" 你是什么意思?
  • 肯定memory_order_acq_rel 不只是保护引用计数?而是将单独的屏障用作优化,以便仅在引用计数达到 0 时才使用获取屏障?
猜你喜欢
  • 2018-01-16
  • 1970-01-01
  • 2012-10-04
  • 2021-03-20
  • 1970-01-01
  • 2020-12-06
  • 2011-03-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多