【面经】shared_ptr的线程安全问题

一句话总结shared_ptr的线程安全问题

我把智能指针的线程安全问题单拎出来讲,是因为在校招面试中可能会被问到。下面,我来谈谈我对这个问题的看法。

这个问题可以被总结为一句话:shared_ptr的引用计数是线程安全的,但shared_ptr实例不是线程安全的,且shared_ptr指向的资源不是线程安全的。

为了把这句话解释清楚,我来给大家举两个例子。

例一

例一:这个例子很好的阐述了shared_ptr的引用计数是线程安全的,shared_ptr指向的资源不是线程安全的。

复制代码
#include <iostream>
#include <memory>
#include <thread>
#include <list>
#include <mutex>
using namespace std;

mutex mtx;
void func(shared_ptr<list<int>> ptr)
{
    for (int i = 0; i < 1000; i++)
    {
        shared_ptr<list<int>> ptr1(ptr);
        mtx.lock();
        ptr1->push_back(i);
        mtx.unlock();
    }
}

int main()
{
    shared_ptr<list<int>> ptr(new list<int>);
    thread t1(func, ptr);
    thread t2(func, ptr);

    t1.join();
    t2.join();
    cout << ptr->size()<<endl;
    return 0;
}

1.ptr是共享资源,shared_ptr中的引用计数是同一份资源,在用ptr拷贝构造ptr1的过程中,会改变引用计数,理应加锁。但引用计数的加减操作是原子的,因此,这种仅修改引用计数的情况是线程安全的,无需加锁。

2.但ptr指向的list是共享资源,对list的写入需要加锁。

以上运行结果是加锁的情况。

以上运行结果是没有加锁的情况,可以看到,对list进行2K次写入,实际上写入的值往往不到2K,具体写入的值随机。

例二

shared_ptr发生拷贝的流程:

1)拷贝智能指针指向的资源(非原子操作)

2)增减引用计数(原子操作)

假如有下面三个同类型的shared_ptr:

1)一开始他们之间的关系可以用下图来表示:

2)然后线程A先执行语句:p1=p2,在执行这条语句时,先改变ptr的指向,然后才修改引用计数。因为现在是多线程,所以很可能出现这样的情况:在线程A执行完步骤一时,还没来得及执行步骤二,就轮到线程B来执行。如下图所示:

3)现在线程B开始执行p2=p3,并且没有被打断,也就是说步骤一二都完成。

先是步骤一:

然后步骤二:

注意此时因为第一个资源的引用计数已经为0,所以会销毁该资源,也就是说,步骤二执行完之后,p1的ptr是一个悬空指针。所以多个shared_ptr对象对其所管理的资源的访问不是线程安全的。如果不使用锁这会造成线程安全问题。

结论:

1.对于同一个shared_ptr实例,在多线程中'读'(如拷贝构造)是线程安全的。

2.对于同一个shared_ptr实例,在多线程中'写'或'读'和'写'都不是线程安全的,都需要加锁。

3.对于共享引用计数的shared_ptr,在多线程中的'读''写'都是线程安全的。

相关推荐
青少儿编程课堂1 小时前
蓝桥杯青少组图形化 STEMA 省考(报名倒计时·11/22开考)+ 全国青少年信息素养大赛 2026—2027赛季 + 电子学会图形化考级:校园华容道大闯关
c++·python·算法·bfs·信息学竞赛
白杨尚青2 小时前
C++进阶篇(五):红黑树——四条规则、三种插入情况与旋转变色
开发语言·数据结构·c++·stl·红黑树·平衡二叉树
旖旎夜光2 小时前
【C++ 基础入门】C++ 继承(上):概念、切片、隐藏、默认成员函数与友元
c++·笔记·学习
apcipot_rain3 小时前
C++转Java日记(05)
java·开发语言·c++
apcipot_rain12 小时前
C++转Java日记(04)
java·开发语言·c++
WL学习笔记14 小时前
vector模拟实现
c++
蜗牛一步步往上爬16 小时前
第十六章 C++语言在深度学习中的应用
开发语言·c++·深度学习
wo_jack20 小时前
C++ 入门笔记(十六):第16课 vector 模拟实现十问十答 —— 从三指针到迭代器失效
c++·后端·面试·stl·vector
D e re k ZH21 小时前
C++ 标准库算法全景指南
数据结构·c++·算法
雪落漂泊1 天前
C++算法 二分查找篇(上)
开发语言·c++·算法