多线程环境下智能指针的正确性:引用计数是否会被线程操作破坏?
智能指针在多线程环境下的线程安全性分析
首先得明确:不同类型的智能指针线程安全特性差异很大,核心要看具体是哪种智能指针,以及对应的操作场景。
std::shared_ptr 的线程安全表现
- 引用计数操作是原子安全的:当多个线程同时复制指向同一对象的不同shared_ptr实例时,引用计数的增减是原子操作,不会出现计数异常、竞态导致的计数错误问题。比如线程A持有
ptr_a指向对象X,线程B持有ptr_b也指向X,两个线程同时执行auto tmp_a = ptr_a和auto tmp_b = ptr_b,引用计数会正确从2增加到4,不会乱套。 - shared_ptr实例本身并非线程安全:如果多个线程直接对同一个shared_ptr变量进行读写操作(比如一个线程给它赋值新的对象,另一个线程复制它),这时候会有竞态风险。因为shared_ptr内部包含原始指针和引用计数两个成员,赋值这类操作不是原子的,可能出现复制操作拿到旧指针但引用计数已经被修改的情况,导致内存泄漏或野指针。这种场景下需要额外的同步措施,比如加锁,或者使用C++20引入的
std::atomic<std::shared_ptr>来保证线程安全。
其他智能指针的情况
std::unique_ptr:它本身不支持复制,只能移动。多线程下如果同时操作同一个unique_ptr实例(比如一个线程移动它,另一个线程访问它),必然会触发未定义行为,完全不具备线程安全性。std::weak_ptr:它的线程安全特性和shared_ptr一致,对同一个weak_ptr实例的多线程读写同样需要同步,但它的lock()操作涉及的引用计数变更也是原子安全的。
内容的提问来源于stack exchange,提问作者FourierFlux
相关产品推荐
相关产品推荐

