c++ lambda捕获this 导致多线程下类释放后还在使用的错误

但是需要注意的是,这里捕获this,不是以一种拷贝的方式,更像是一种引用(或者别名,描述可能不准确),当在外面这个类的生命周期结束时,lambda内部还在调用这个类的成员函数,那么就会出错

我遇到的问题是 捕获了类A的this,对A的一个shared_ptr进行操作。偶然会出现shared_ptr的内部基类spt_count_base的报错。看了下这个shared_ptr 的use_count和weak_count都是0,

这就非常奇怪。shared_ptr计数是线程安全的,(但是实际指向对象和计数不是原子操作),并且访问这个sptr也加了锁,为什么会出现被释放了的情况。

大概再说下情景

class A

shared_ptr sptr;

sptr.func = this{ do something};

class B

shared_ptr

func()

//概率崩溃
sptrMap.erase();

当A被析构后,B注册的回调被另一个线程调用了func();这时可能会出现A开始析构,刚好析构到B,并且B的sptrMap已经析构时,出现崩溃。但这个顺序不是确定的无法保证,所以也不一定必出现这种现象。

防止这种现象可以加个判断,在sptrMAp不为空时不进行析构。或者用weak_ptr.在捕获this前,用 weak_ptr p = std::shared_from_this;然后在lambda最开始用p.lock判断A是否释放

通过这个了解到了lambda捕获的一个坑,及类析构的顺序及析构时线程安全的保护

另附实际代码

Original: https://www.cnblogs.com/wangshaowei/p/14696424.html
Author: 大老虎打老虎
Title: c++ lambda捕获this 导致多线程下类释放后还在使用的错误

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/535272/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • c++ union内存

    看一个例子: 输出结果: 为什么是这样的呢? 因为A是union,所以在内存中存储的格式为: 高地址 ————> 低地址 12…

    C++ 2023年5月29日
    049
  • C++ 硬核知识点: 数据段/代码段/内存分配/虚函数/继承/多态

    结构体struct和类class占用内存大小解析 今天面试遇到一个比较有意思的问题, 这里安排一下空结构体和空类占内存大小是多少? 答案:1. C++指定空结构体和空类所占内存大小…

    C++ 2023年5月29日
    090
  • 【转】C++知识点总结

    其他路径: 微信公众号:程序喵星人 更多资源和视频教程,QQ:1902686547 这篇文章是对C++的知识点做了一些简单的总结,基本包含了所有的C++基础知识点。以下提到的知识点…

    C++ 2023年5月29日
    052
  • C++20新特性

    conceptrequiresconstinitconstevalco_awaitco_returnco_yieldchar8_t 优点:1)没有头文件;2)声明实现仍然可分离, …

    C++ 2023年5月29日
    067
  • 从C++到GO

    刚开始接触Go语言,看了两本Go语言的书,从c++开发者的角度来看看go语言的新特性,说下自己感触较深的几点: 并发编程 Go语言层面支持协程,将并发业务逻辑从异步转为同步,大幅提…

    C++ 2023年5月29日
    052
  • 【面试攻略】C++面试-边锋

    2020-11-26-边锋 1.说说你以前的架构2.C++11特性,好像问到了这个constexpr https://www.jianshu.com/p/5480c4a35d1d3…

    C++ 2023年5月29日
    060
  • C++中的float&double的存储原理

    参考:https://cloud.tencent.com/developer/article/1473541 对于任何数字表示成二进制科学计数法以后,一定是1点几(尾数)乘以2的多…

    C++ 2023年5月29日
    041
  • Microsoft Visual C++ 2019 v14.28.29617

    Microsoft Visual C++ Redistributable(系统运行库,简称MSVC,VB/VC)是Windows操作系统应用程序的基础类型库组件。 Microsof…

    C++ 2023年5月29日
    093
  • C#调用C++的dll两种方法(托管与非托管)

    C#与C++交互,总体来说可以有两种方法: 利用PInvoke实现直接调用 非托管C+ 利用C++/CLI作为代理中间层 一、非托管C++ 由于C#编写的是托管代码,编译生成微软中…

    C++ 2023年5月29日
    050
  • EclipseC++学习笔记-5 隐藏cmd窗口

    每次启动eclipse后,会有一个cmd窗口,很影响整洁解决办法示例:powershell.exe -WindowStyle Hidden -c wsl — /root…

    C++ 2023年5月29日
    067
  • Dev-C++

    官网: http://orwelldevcpp.blogspot.com/ 最新版本: Version 5.11 – 27 April 2015 下载链接: https…

    C++ 2023年5月29日
    064
  • Silverlight5通过P/Invoke调用自定义C/C++ DLL(Lua)

    注1:为了确保silverilght5在浏览器或桌面上成功调用win32 DLL,必须在项目属性中勾选相应的权限: 勾选Enable running application out…

    C++ 2023年5月29日
    074
  • C++内存分配方式详解——堆、栈、自由存储区、全局/静态存储区和常量存储区

    栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清除的变量的存储区。里面的变量通常是局部变量、函数参数等。在一个进程中,位于用户虚拟地址空间顶部的是用户栈,编译器用它来实现…

    C++ 2023年5月29日
    069
  • C++11 并发指南六(atomic 类型详解三 std::atomic (续))

    总地来说,C++11 标准库中的 std::atomic 针对整形(integral)和指针类型的特化版本新增了一些算术运算和逻辑运算操作。具体如下: 下面我们来简单介绍以上的 s…

    C++ 2023年5月29日
    039
  • 关于C++ const 的全面总结

    C++中的const关键字的用法非常灵活,而使用const将大大改善程序的健壮性,本人根据各方面查到的资料进行总结如下,期望对朋友们有所帮助。 Const 是C++中常用的类型修饰…

    C++ 2023年5月29日
    043
  • C++ 求时差

    C++ 求时差的三种方法 【1】标准C库方式 示例代码 【2】C++库方式 C++11之后才引入 示例代码: 【3】windows API方式 示例代码: 为什么第14行,我们把G…

    C++ 2023年5月29日
    077
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球