C++智能指针与内存模型:为何控制块引用计数增量无需同步?
为什么智能指针引用计数的增量操作可以用memory_order_relaxed?
我研究了Stack Overflow上《How can memory_order_relaxed work for incrementing atomic reference counts in smart pointers?》的问题,相关代码如下:
// 线程A: // 智能指针拷贝构造函数 smart_ptr(const smart_ptr& other) { ... control_block_ptr = other->control_block_ptr; control_block_ptr->refs.fetch_add(1, memory_order_relaxed); ... } // 线程D: // 智能指针析构函数 ~smart_ptr() { if (control_block_ptr->refs.fetch_sub(1, memory_order_acq_rel) == 1) { delete control_block_ptr; } }
我始终无法理解,为什么引用计数的增量操作可以使用memory_order_relaxed。
有回答提到:
引用计数的增加操作永远可以用memory_order_relaxed:对象的新引用只能从已有的引用生成,而把已有引用从一个线程传递到另一个线程的过程,必然已经提供了所有必要的同步。
另外我还看到这样的说法:
增量操作可以用relaxed(这不是发布操作,没有操作依赖于这个增量)
这些内容都暗示增量操作是独立的,cppreference也说明relaxed内存序适用于独立增量。但在上述示例中,增量并非独立——存在并发的减量操作,而且减量操作依赖增量(当读取到引用计数为1时会删除对象)。我担心用relaxed做增量会导致线程看不到这个增量,进而提前删除对象;就算RMW操作总能读取到最新值,不同线程看到的增减顺序也可能不一样,我不清楚执行减量的线程最终会看到什么。这难道没有问题吗?增量操作难道不需要和减量操作同步吗?我实在没法理解这两段简短的解释。
内容的提问来源于stack exchange,提问作者JenyaKh
相关产品推荐
相关产品推荐

