C++ 智能指针线程安全的问题

1. 线程安全的定义

多线程操作一个共享数据的时候,保证所有线程的行为是符合预期的则称为线程安全。

2. 智能指针的线程安全

2.1 智能指针的线程安全隐患(shared_ptr)

主要是以下几个方面:
(1) 引用计数的加减操作是否线程安全。
(2) 修改shared_ptr指向是否线程安全。
(3) shared_ptr<T>的T的并发操作的安全性,也应该被讨论。

2.2 引用计数的讨论

shared_ptr中除了有一个指针,指向所管理数据的地址。还有一个指针执行一个控制块的地址,里面存放了所管理数据的数量(常说的引用计数)、weak_ptr的数量、删除器、分配器等。

也就是说对于引用计数这一变量的存储,是在堆上的,多个shared_ptr的对象都指向同一个堆地址。在多线程环境下,管理同一个数据的shared_ptr在进行计数的增加或减少的时候是线程安全的吗?

答案是肯定的,这一操作是原子操作。
结论共享引用计数的不同的shared_ptr被多个线程写,是线程安全的

2.3 修改指向是否线程安全

场景一:同一个shared_ptr被多个线程写

先给出结论:此时不是线程安全的

首先回顾一下shared_ptr指针的内部结构,包含两个重要的变量:ptr指针引用计数指针

对于shared_ptr的复制则分为两个步骤:

  1. 复制ptr指针
  2. 复制引用计数指针

引用例子: 陈硕:智能指针的探讨
考虑一个简单的场景,有 3 个 shared_ptr 对象 x、g、n:

shared_ptr<Foo> g(new Foo); // 线程之间共享的 shared_ptr
shared_ptr<Foo> x; // 线程 A 的局部变量
shared_ptr<Foo> n(new Foo); // 线程 B 的局部变量

在这里插入图片描述
结论同一个shared_ptr被多个线程写,不是线程安全的

场景二:同一个shared_ptr被多个线程读;

仅仅是读取,而未修改数据所以给出结论:
同一个shared_ptr被多个线程“读”是安全的

3. 结论

通过分析,印证boost官方文档中的以下结论:

1)同一个shared_ptr被多个线程“读”是安全的;

2)同一个shared_ptr被多个线程“写”是不安全的;

3)共享引用计数的不同的shared_ptr被多个线程”写“ 是安全的;

参考
陈硕Blog.
c++ 11 的shared_ptr多线程安全?.

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值