std::shared_ptr引用计数并发增减的线程安全问题问询
我了解到std::shared_ptr<T>的引用计数通常通过带std::memory_order_relaxed的std::atomic实现,因此本身具备线程安全性,但我仍不清楚它如何在引用计数并发增减的场景下保证线程安全。
竞态场景示例
Thread 1:
- 析构
shared_ptr<T> - 执行
rc.fetch_sub(1) - 得到引用计数RC == 0,判定自己是最后持有者
- 调用
T::~T()
- 析构
Thread 2:
- 并发拷贝该
shared_ptr<T> - 执行
rc.fetch_add(1) - 得到引用计数RC == 1,判定拷贝后的
shared_ptr有效 - 解引用
shared_ptr - 访问已析构的T!
- 并发拷贝该
这种竞态场景并非不可能,以下是手动构造的极端示例代码:
std::shared_ptr<T> ptr; int main() { std::thread t([&ptr] () { ptr = std::make_shared<int>(); } // 引用计数在此处减少!调用~T() ); auto ptr2 = ptr; // 引用计数在此处增加! ptr2->some_function(); // 访问已析构对象! t.join(); }
我的问题
- C++标准对此种情况是如何规定的?
std::shared_ptr<T>是否能确保引用计数并发增减时的线程安全?
内容的提问来源于stack exchange,提问作者Bin Yan
相关产品推荐
相关产品推荐

