首页 > 其他分享 >std::shared_ptr 线程安全方面的思考

std::shared_ptr 线程安全方面的思考

时间:2023-08-04 18:58:04浏览次数:39  
标签:std 指向 安全 线程 shared ptr

一直惦记着 std::shared_ptr 线程安全的问题,看了些文章后,又怕过段时间忘记了,遂记录下来

std::shared_ptr 的线程安全问题主要有以下两种:

  • 引用计数的加减操作是否线程安全
  • std::shared_ptr 修改指向时是否线程安全

第一个问题的答案: 是线程安全的,因为是原子操作

注意:

引用计数这一变量的存储,是在堆上的,多个 std::shared_ptr 的对象都指向同一个堆地址

第二个问题的答案:不是线程安全,因为在修改指向时,计数会减一,加减的操作并不是原子的,所以可能存在其他线程也在修改它的指向

这种情况可能会导致计数在操作减一的时候,其内部的指向,已经被其他线程修改过了。引用计数的异常会导致某个管理的对象被提前析构,后续在使用到该数据的时候触发 coredump

例子可以参考高赞答案:C++11 的 shared_ptr 多线程安全?

解决方法很简单,C++20 出了一个原子操作的指向=》std::atomic<std::shared_ptr>

如果没有到 C++20,针对这种问题,可以考虑加锁或者避免在多线程中修改智能指针的指向

标签:std,指向,安全,线程,shared,ptr
From: https://www.cnblogs.com/strive-sun/p/17606752.html

相关文章

  • 简简单单,带你学会使用Java线程池
    在前面几篇文章中,波哥给小伙伴们讲解了什么是线程,以及创建线程的几种方法。这就有小伙伴问了,我们工作中用得最多的是线程池,波哥你能不能再给我们讲一讲线程池呀?既然小伙伴们提出需求了,波哥我就得满足大家了,今天我就为小伙伴们讲一讲线程池! 一.线程池1.什么是线程池在面向对象编程......
  • Linux系统服务器启动SSH服务时出现“error while loading shared libraries”错误该如
    问题描述本文主要介绍在Linux系统服务器启动SSH服务时,命令行或secure日志文件出现类似如下的错误信息。· errorwhileloadingsharedlibraries:libcrypto.so.10:cannotopensharedobjectfile:Nosuchfileordirectory.· PAMunabletodlopen(/usr/lib64/security/pam......
  • 非root用户解决Rstudo安装R包时报错 libpng16.so.16: cannot open shared object file
    在安装好几个R包的时候都出现了这个报错,看网上的解决方法都是root用户才能干的,我只是普通用户没法办,本来想忍忍就过去了,可是今天装个Deseq2都装不起来,并报错:libpng-config:commandnotfoundread.c:3:17:fatalerror:png.h:Nosuchfileordirectory所以我下定决心一定要......
  • C++多线程中互斥量的使用
    多线程中互斥信号量(Mutex)的使用1.0互斥量的基本概念1.1Example\(\quad\)首先我们要明白,为什么会有互斥信号量的出现,在多线程编程中,不同的线程之间往往要对同一个数据进行操作,如果该数据是只读的,当然不会出现什么问题,但是如果两个线程同时对某个数据进行写操作,则可能出现难以......
  • 为什么有了gil锁还要互斥锁,进程,线程和协程 ,什么是鸭子类型
    1为什么有了gil锁还要互斥锁-gil锁,全局解释器锁,线程需要运行需要得到gil锁,gil锁不能控制用户级别的安全-#互斥锁,为了保证多线程并发操作数据而设置的锁,保证在加锁和释放锁之间,其他线程不能操作,让并行变成串行,牺牲效率-起两个线程。执行任务,x=x+1,x开始等于0-1第一个线程过来......
  • 线程的五个状态(文字+图示)
    线程五个状态1、新建状态(New):新创建了一个线程对象,和其他java对象一样,仅在堆中分配内存。2、就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待被线程调度选中,获取CPU的使用权。(指线程已具备了各种执行条件,只......
  • Java多线程总结(超详细总结)
    (Java多线程总结)1.创建线程的方式方式1继承于Thread类创建一个继承于Thread类的子类重写Thread类的run()-->将此线程执行的操作声明在run()中创建Thread类的子类的对象4.通过此对象调用start()例子:遍历100以内的所有的偶数classMyThreadextendsThread{//......
  • 为什么程序计数器、虚拟机栈和本地方法栈是线程私有的呢?为什么堆和方法区是线程共享的
    程序计数器、虚拟机栈和本地方法栈是线程私有的,而堆和方法区是线程共享的,这是由于它们在Java虚拟机中的作用和特性所决定的。程序计数器:程序计数器是一块较小的内存区域,用于存储当前线程正在执行的字节码指令的地址。每个线程都有自己独立的程序计数器,用于记录各自线程的执行......
  • Qt 在线程中invokeMethod采用QueuedConnection模式,调用带指针参数槽,实际不会调用
    widgetObject有操函数Test:voidTest(int*v);在线程中调用Test,会被忽略,实际不会调用。QMetaObject::invokeMethod(widgetObject,"Test",Qt::QueuedConnection,Q_ARG(int*,&v));下面是网上找的理由: 在同一个线程中当信号和槽都在同一个线程中时,值传递参数和引用传递参数有......
  • 解读 --- System.Windows.Forms.Timer是前台线程吗?
    引言今天同事问了我一个问题,System.Windows.Forms.Timer是前台线程还是后台线程,我当时想的是它是跟着UI线程一起结束的,应该是前台线程吧?我确实没有仔细研究过他们的异同,所以带着这个疑问探究一下System.Windows.Forms.Timer。System.Windows.Forms.Timer机制System.Windows.F......