为什么在引用计数器上需要内存顺序限制
Why there need memory order limit on reference counter?
以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:除了原子op上的memory_order_release,为什么在删除前还有一个memory_order_acquire ?
对于第一个问题,它防止(*x)
的任何使用在fetch_sub
之后重新排序(当引用计数可能为0并且因此禁止使用时)。可能原因是CPU重排序或编译器重排序。第二个问题只是释放的镜像;释放保护存储,获取保护负载。
看起来refcount_fetch_sub(1, memory_order_acq_rel)
也可以工作,但它只保护了refcount。
相关文章:
- 具有内存顺序的原子负载存储
- 原子加载和存储与内存顺序放宽
- 内存排序或读取-修改-写入操作,仅(读/写)内存顺序
- 理解C++内存顺序,我错了吗?
- 初始化值是否保证通过其自己的地址反映,而不考虑内存顺序
- 如果 RMW 操作没有任何变化,是否可以针对所有内存顺序对其进行优化
- 多个线程之间的获取-释放内存顺序
- 松弛的内存顺序会导致无限循环吗?
- 是否可以使用松弛的内存顺序来观察条件?
- 共享指针析构函数中的内存顺序
- C++中的类私有成员的内存顺序是否得到保证?
- 将fetch_add与宽松的内存顺序返回唯一值
- 混合放松和释放获取内存顺序
- 使用C++原子库,我应该使用什么样的内存顺序进行加载,然后进行比较交换
- 当某些错误可以接受时,顺序加载存储原子的内存顺序应该是什么
- 获取释放内存顺序与顺序一致性不同的实际示例是什么?
- 发行语义中的内存操作 - C 11的内存顺序
- 我应该为等待工作线程的主线程使用哪种内存顺序
- OpenMP原子内存顺序
- "acquire" 和"consume"内存顺序有何不同,何时"consume"可取?