std::shared_ptr的引用计数线程安全,但共享对象访问和指针本身操作需同步。

智能指针是否线程安全,取决于具体类型和使用方式。std::shared_ptr 和 std::weak_ptr 的控制块(包含引用计数)在多线程环境下通过原子操作保障,但智能指针本身的操作并非完全线程安全,需谨慎使用。
std::shared_ptr 的引用计数是原子的
std::shared_ptr 的线程安全性主要体现在其内部引用计数的增减是通过原子操作完成的。这意味着:
- 多个线程同时拷贝或析构 shared_ptr 实例时,引用计数能正确更新,不会出现竞态条件。
- 多个线程持有同一个 shared_ptr 对象的副本并各自管理生命周期是安全的。
例如:
// 线程1std::shared_ptr
// 线程2
std::shared_ptr
这种共享拷贝行为,引用计数的修改是线程安全的。
shared_ptr 的读写操作仍需同步
虽然引用计数是原子的,但 shared_ptr 变量本身的读写不是原子操作。如果多个线程同时访问同一个 shared_ptr 对象(而非副本),必须加锁保护。
- 两个线程同时对同一个 shared_ptr 变量赋值或重置,会导致未定义行为。
- 例如:一个线程在执行 ptr = nullptr,另一个线程在执行 ptr = other_ptr,这需要互斥锁保护。
指向对象的内容不保证线程安全
shared_ptr 仅保证自身控制块(引用计数)的线程安全,不保护其所指向对象的内容。
- 多个线程通过 shared_ptr 访问同一对象的成员变量或方法时,仍需额外同步机制(如 mutex)。
- 例如:两个线程同时调用 ptr->data = 100,即使 ptr 是 shared_ptr,也需要同步。
std::make_shared 提升效率与安全性
使用 std::make_shared
- 原子地分配对象和控制块,减少内存泄漏风险。
- 提升性能,避免多次内存分配。
- 在多线程初始化场景中更推荐使用。
基本上就这些。引用计数安全,不代表使用方式就安全。多线程下操作 shared_ptr 变量本身要加锁,操作其指向数据也要同步。理解清楚层级,才能避免隐患。










