线程中的异常可以使用 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. [转帖]聊聊hikari连接池的leakDetectionThreshold

    http://www.manongjc.com/detail/52-hjoufmsfhtsqvgp.html 本文章向大家介绍聊聊hikari连接池的leakDetectionThreshold,主要 ...

  2. [转帖] q命令-用SQL分析文本文件

    https://www.cnblogs.com/codelogs/p/16060830.html 简介# 在Linux上分析文本文件时,一般会使用到grep.sed.awk.sort.uniq等命令, ...

  3. [转帖]耗时几个月,终于找到了JVM停顿十几秒的原因

    https://www.cnblogs.com/codelogs/p/16060792.html   原创:打码日记(微信公众号ID:codelogs),欢迎分享,转载请保留出处. 简介# 最近我们系 ...

  4. [转帖]Native Memory Tracking 详解(3):追踪区域分析(二)

    https://www.modb.pro/db/539804 上篇文章 Native Memory Tracking 详解(2):追踪区域分析(一) 中,分享了NMT追踪区域的部分内存类型--Java ...

  5. postman中monitor的使用

    monitor就是一个摸鱼的功能,我们把写好的接口部署到postman的web服务器中, 绑定自己的邮箱,运行结果会发送到自己的邮箱中,不用实时监控,是个非常方便 的功能(不安全) 1.crete a ...

  6. 一文搞懂Go GC演进史,讲的太细致了!

    最近在和 Go就业训练营 的朋友讨论Go GC的问题,发现了刘丹冰老师总结的内容,写的太好了,和大家分享一下. 我们的讨论和思考也整理到这篇文章中了,希望对你有启发. 垃圾回收(Garbage Col ...

  7. webservice--WSDL文件生成本地的代理类

    我们在对应第三方接口时常用:项目上右键---->服务引用---->WCF Web Service,如下图的页面----->填好url后---->转到,就可以发现服务,生成代理类 ...

  8. CouchDB vs. LevelDB

    CouchDB 和 LevelDB 都是数据库系统,但它们在很多方面有着不同的设计和应用重点.下面是对这两个数据库在一些关键点上的对比: 数据模型: CouchDB:CouchDB 是一种面向文档的数 ...

  9. 从嘉手札<2024-1-10.2>

    我们每个人都是在受挫中成长起来的 你不能剥夺他人在受苦中获益的权利 大部分人对吃苦的含义可能理解的太肤浅了 穷并不是吃苦 吃苦的本质是长时间为了某个目标而聚焦的能力 在这个过程中放弃娱乐生活.放弃无效 ...

  10. Gin 中间件

    中间件 在Gin框架中,中间件(Middleware)指的是可以拦截http请求-响应生命周期的特殊函数,在请求-响应生命周期中可以注册多个中间件,每个中间件执行不同的功能,一个中间执行完再轮到下一个 ...