C++智能指针线程安全 原子操作保障

shared_ptr引用计数线程安全,但多线程读写同一shared_ptr变量需用std::atomic<shared_ptr<T>>;unique_ptr不可共享,跨线程传递需std::move并确保所有权清晰;智能指针不保证所指对象的线程安全,访问共享对象仍需同步机制

C++智能指针线程安全 原子操作保障

智能指针在多线程环境下使用时,线程安全问题必须谨慎处理。c++标准库中的智能指针各有不同的线程安全特性,理解这些特性并结合原子操作,是保障并发安全的关键。

shared_ptr 的线程安全机制

shared_ptr 的引用计数是线程安全的,这意味着多个线程同时增加或减少引用计数不会导致数据竞争。标准要求对引用计数的修改是原子的。

但注意:多个线程读写同一个 shared_ptr 对象(即指向同一块控制块的多个副本)时,如果涉及赋值或重置,仍需外部同步。

常见场景:

  • 线程A和线程B各自持有同一个 shared_ptr 的副本,各自析构时引用计数自动减一,安全。
  • 线程A和线程B同时对同一个 shared_ptr 变量进行赋值(如 sp = new_ptr),则必须加锁或使用原子操作。

使用 atomic_shared_ptr 保障操作原子性

C++11起,可以通过 std::atomic_loadstd::atomic_store 等函数对 shared_ptr 进行原子读写。但从 C++20 开始,推荐使用 std::atomic<std::shared_ptr<T>>,它提供了更直观的接口

立即学习C++免费学习笔记(深入)”;

例如:

std::atomic<std::shared_ptr<Data>> global_data;  // 线程中安全更新 auto new_data = std::make_shared<Data>(); global_data.store(new_data);  // 安全读取 auto current = global_data.load(); 

这样可以避免多个线程同时修改同一个 shared_ptr 变量导致的竞争。

unique_ptr 的线程安全特点

unique_ptr 不支持共享,本身不可复制,通常只在一个线程中持有。因此,它不涉及引用计数,也没有内置的线程安全机制。

如果需要跨线程转移所有权,应使用 std::move,并在转移时确保没有其他线程正在访问该指针。典型做法是配合互斥锁或通过消息队列传递 unique_ptr。

避免常见陷阱

即使引用计数安全,也不能忽视对所指向对象的访问安全。多个 shared_ptr 共享同一个对象时,对象本身的读写仍需同步机制保护。

关键点总结:

  • shared_ptr 的引用计数线程安全,操作 shared_ptr 变量本身不一定安全。
  • 多线程读写同一 shared_ptr 变量时,使用 std::atomic<shared_ptr<T>>。
  • unique_ptr 应避免共享,跨线程传递需确保所有权清晰。
  • 智能指针安全不等于所指对象安全,对象访问仍需加锁或其它同步手段。

基本上就这些。合理使用原子智能指针和同步机制,能有效避免资源泄漏和竞态条件。

© 版权声明
THE END
喜欢就支持一下吧
点赞13 分享