线程中的异常可以使用 std::rethrow_exception 抛给主线程

问题分析:一个线程中抛出的异常是没法被另一个线程捕获的。假如我们在主线程中创建一个子线程,子线程中的函数抛出了异常,主线程的 catch 是不会触发,如下,

#include<iostream>
#include<thread>
#include<exception>
#include<stdexcept> static std::exception_ptr teptr = nullptr; void LaunchRocket()
{
throw std::runtime_error("Catch me in MAIN");
} int main()
{
try
{
std::thread t1(LaunchRocket);
t1.join();
}
catch (const std::exception &ex)
{
std::cout << "Thread exited with exception: " << ex.what() << "\n";
} return 0;
}

LaunchRocket() 会抛出异常,但是主线程的 catch 不会触发。

如果我们需要在程序崩溃的同时,希望在主线程中做出处理,那可以使用 std::exception_ptr 去捕获异常并抛给后台的线程,比如主线程

步骤:

1. 创建一个全局的 globalExceptionPr 的实例,并初始化为 nullptr

2. 在子线程中抛出异常后,在 catch 代码段将 std::current_exception() 赋值给 globalExceptionPr

3. 在主线程中检查 globalExceptionPr 是否被设置了

4. 如果为真,使用 std::rethrow_exception(exception_ptr p) 重新抛出由 exception_ptr 参数引用的异常

如下为修改后的例子,

#include<iostream>
#include<thread>
#include<exception>
#include<stdexcept> static std::exception_ptr globalExceptionPtr = nullptr; void LaunchRocket()
{
try
{
std::this_thread::sleep_for(std::chrono::milliseconds(100));
throw std::runtime_error("Catch me in MAIN");
}
catch (...)
{
//Set the global exception pointer in case of an exception
globalExceptionPtr = std::current_exception();
}
} int main()
{
std::thread t1(LaunchRocket);
t1.join(); if (globalExceptionPtr)
{
try
{
std::rethrow_exception(globalExceptionPtr);
}
catch (const std::exception &ex)
{
std::cout << "Thread exited with exception: " << ex.what() << "\n";
}
} return 0;
}

调试结果:Thread exited with exception: Catch me in MAIN

C++ 多线程的错误和如何避免(10)的更多相关文章

  1. Java程序员最常犯的错误盘点之Top 10

    1. 数组转ArrayList 为了实现把一个数组转换成一个ArrayList,很多Java程序员会使用如下的代码: Arrays.asList确实会返回一个ArrayList对象,但是该类是Arra ...

  2. maven 编译的时候总是报一些奇怪的错误 比如 surefire-boot 2.10 .jar 可是私服里查看本来就没有这个高的版本。

    或者私服总是 报 read time out , 或者  io 错误,  或者 gzip 解压错误,或者总是尝试下载一些高版本的jar , 而这些jar 可能是不存在的 .. 尝试 重新下载 apac ...

  3. c++多线程崩溃错误1

    主线程中的子线程没有jion,导致主线程马上结束,子线程对象被释放掉,而子线程还在后台继续执行导致崩溃 int main() OBJ = classA() OBJ.START()//在start函数中 ...

  4. sdb报告-10 错误问题定位

    # sdb报告-10 错误问题定位在sdb 的集群环境中,如果面对的是一个高并发的操作场景,有时候会莫名其妙地报告 -10 错误. 在 sdb 的错误列表中,-10 错误代表:系统错误. 这是一个笼统 ...

  5. Windows 10 L2TP 809错误

    今天不知道为什么,一直工作正常的L2TP不能连接了.我用的是Surface Pro 3,Windows 10 专业版,操作系统一直保持自动更新,而且最近也没有安装什么软件.点击连接后,等一段时间就报8 ...

  6. Node.js权威指南 (10) - Node.js中的错误处理与断言处理

    10.1 使用domain模块处理错误 / 272 10.1.1 domain模块概述 / 272 10.1.2 创建并使用Domain对象 / 274 10.1.3 隐式绑定与显式绑定 / 276 ...

  7. C# 多线程学习笔记 - 3

    本文主要针对 GKarch 相关文章留作笔记,仅在原文基础上记录了自己的理解与摘抄部分片段. 遵循原作者的 CC 3.0 协议. 如果想要了解更加详细的文章信息内容,请访问下列地址进行学习. 原文章地 ...

  8. Java多线程知识总结(一)

    一.创建线程的三种方式: 创建线程的方式有三种,一是创建Thread实例,二是实现Runnable接口,三是实现Callable接口,Runnable接口和Callable接口的区别是一个无返回值,一 ...

  9. Java回顾之多线程同步

    在这篇文章里,我们关注线程同步的话题.这是比多线程更复杂,稍不留意,我们就会“掉到坑里”,而且和单线程程序不同,多线程的错误是否每次都出现,也是不固定的,这给调试也带来了很大的挑战. 在这篇文章里,我 ...

  10. 2019年北航OO第二单元(多线程电梯任务)总结

    一.三次作业总结 1. 说在前面 对于这次的这三次电梯作业,我采用了和几乎所有人都不同的架构:将每个人当作一个线程.这样做有一定的好处:它使得整个问题的建模更加自然,并且在后期人员调度变得复杂时,可以 ...

随机推荐

  1. [转帖]SQL Server 性能调优

      性能调优2:CPU   关系型数据库严重依赖底层的硬件资源,CPU是服务器的大脑,当CPU开销很高时,内存和硬盘系统都会产生不必需要的压力.CPU的性能问题,直观来看,就是任务管理器中看到的CPU ...

  2. [转帖]MegaRaidCli64 常用命令解释

    MegaRaidCli64 常用命令解释 安装 查看 创建 删除 案例 安装 Centos wget https://docs.broadcom.com/docs-and-downloads/raid ...

  3. [转帖]深入理解mysql-第十一章 mysql查询优化-Explain 详解(中)

    一.执行计划-type属性 执行计划的一条记录就代表着MySQL对某个表的执行查询时的访问方法,其中的type列就表明了这个访问这个单表的方法具体是什么,比方说下边这个查询: mysql> EX ...

  4. STM32CubeMX教程24 WDG - 独立窗口看门狗

    1.准备材料 开发板(正点原子stm32f407探索者开发板V2.4) STM32CubeMX软件(Version 6.10.0) 野火DAP仿真器 keil µVision5 IDE(MDK-Arm ...

  5. Vant中List列表下拉加载更多

    van-list上只有一层父级元素div,多了可能下拉加载出不来:或者更多 <template> <div class="scholl-declarepage"& ...

  6. Liunx网络配置

    1.安装精简版:CentOS-7-x86_64-Minimal-2009.iso 2.进入配置文件:  vi /etc/sysconfig/network-scripts/ifcfg-ens33 3. ...

  7. 开源项目01--WTM

    一.项目名称:WTM 项目所用技术栈: wtm mvvm mvc aspnetcore dotnetcore react vue layui layui-admin element-ui ncc等 项 ...

  8. JS ----- Javascript中apply、call、bind

    这篇文章实在是很难下笔,因为网上相关文章不胜枚举. 巧合的是前些天看到阮老师的一篇文章的一句话: "对我来说,博客首先是一种知识管理工具,其次才是传播工具.我的技术文章,主要用来整理我还不懂 ...

  9. plcTIA Portal V16找不到许可证

    首先快捷键win+s唤出搜索,搜:服务 其次搜索这个服务Automation License Manager Service 右击-启动服务,然后重新启动plc即可选择CPU型号了

  10. WinForm之ComboBox实现模糊查询

    ComboBox实现模糊查询 第一步:在Form_Load事件中绑定数据源 第二步:写一个方法,返回一个List<string>类型的集合来存储控件中的Items 第三步:在Form_Lo ...