1 C++抛出异常与捕获异常
在C++中我们经常使用以下代码抛出异常和捕获异常
#include <iostream>
#include <thread>
#include <exception>
#include <stdexcept>
int main()
{
try
{
throw std::runtime_error("Exception: runtime error in thread");
}
catch (const std::exception& ex)
{
std::cout << "Exited with exception: " << ex.what() << "\n";
}
return 0;
}
上述抛出代码和捕获代码都是在主线程中进行了,我们能够顺利的捕捉到抛出的异常。
那如果我在子线程中抛出异常,在主线程中能捕捉到吗?
C++主线程无法捕获子线程异常!!!
C++在子线程中抛出异常是无法在主线程捕获到的,看以下示例代码
#include <iostream>
#include <thread>
#include <exception>
#include <stdexcept>
void StartThread()
{
throw std::runtime_error("Exception: runtime error in thread");
}
int main()
{
try
{
std::thread thread(StartThread);
thread.join();
}
catch (const std::exception& ex)
{
std::cout << "Thread exited with exception: " << ex.what() << "\n";
}
return 0;
}
执行程序,没有输出任何内容,这说明C++中子线程中抛出的异常无法在主线程中捕获,也就是说一个线程中抛出的异常只能在同一线程捕获。
2 C++如何在主线程中捕获子线程抛出的异常
上面我们了解了在C++中不能在主线程中捕捉到子线程抛出的异常,那么如果业务强制要求需要在主线程中捕获子线程的异常,那么我们该如何实现呢?
理想的一个设计是:
- 在主线程中声明一个变量,将该变量传递到子线程中
- 在子线程抛出异常的时候,修改变量的值为异常值
- 然后在主线程中捕获异常
基于上面的设计,我们使用std::promise
来完成这一实现,先看代码
#include <iostream>
#include <thread>
#include <exception>
#include <stdexcept>
#include <future>
void StartThread(std::promise<void>& promise)
{
try {
std::this_thread::sleep_for(std::chrono::seconds(5));
throw std::runtime_error("Exception: runtime error in thread");
promise.set_value();
}
catch (...)
{
promise.set_exception(std::current_exception());
}
}
int main()
{
std::promise<void> exception_promise;
std::thread thread(std::bind(StartThread, std::ref(exception_promise)));
std::future<void> exception_future = exception_promise.get_future();
// 等待子线程执行完成
for (int i = 0; ; i++)
{
if (exception_future.wait_for(std::chrono::seconds(1)) != std::future_status::timeout)
break;
std::cout << "waiting ... [" << i << "] seconds" << std::endl;
}
try
{
exception_future.get();
}
catch (const std::exception& e)
{
std::cout << "Thread exited with exception: " << e.what() << "\n";
}
thread.join();
return 0;
}
上述代码成功在主线程中捕获到了子线程抛出的异常,运行日志如下
waiting ... [0] seconds
waiting ... [1] seconds
waiting ... [2] seconds
waiting ... [3] seconds
Thread exited with exception: Exception: runtime error in thread
在上述代码中,我们在主线程中声明了一个std::promiss<void>
类型的变量,并传递到子线程中,然后在子线程中使用try catch
语句捕获异常然后设置给std::promise<void>
变量;而在主线程中我们使用std::future
获取到std::promise
的future,然后使用try catch
成功捕捉到设置到std::promise<void>
变量中的异常。
本文作者:StubbornHuang
版权声明:本文为站长原创文章,如果转载请注明原文链接!
原文标题:C++ – 主线程如何捕获子线程抛出的异常
原文链接:https://www.stubbornhuang.com/2713/
发布于:2023年06月30日 13:40:10
修改于:2023年06月30日 13:40:10
当前分类随机文章推荐
- C++ - 只有在Debug模式下才使用std::cout输出调试日志,Release发布版本不输出调试日志 阅读5073次,点赞0次
- C++ - 导出接口函数和导出C++类 阅读868次,点赞0次
- C++ - 最简单的将文本文件的内容一次性读取到std::string的方法 阅读5664次,点赞4次
- C++ - 动态链接库dll为什么要使用unsigned char作为byte的内部格式 阅读994次,点赞0次
- C++ – 字节数组byte[]或者unsigned char[]与long long的相互转换 阅读2177次,点赞0次
- C++ - 使用std::chrono获取当前秒级/毫秒级/微秒级/纳秒级时间戳 阅读5079次,点赞0次
- C++ - 在某一天某个时间点定时执行任务,比如2022年9月19日晚上9点准点执行发送邮件函数 阅读813次,点赞0次
- C++11 - 解析并获取可变参数模板中的所有参数 阅读1618次,点赞0次
- C++ - 将std::vector中的数值拷贝到数组中 阅读3608次,点赞1次
- C++ - 在Visual Studio中使用OpenMP加速for循环 阅读509次,点赞0次
全站随机文章推荐
- Pytorch - nn.Transformer、nn.TransformerEncoderLayer、nn.TransformerEncoder、nn.TransformerDecoder、nn.TransformerDecoder参数详解 阅读4480次,点赞2次
- 资源分享 - Game AI Pro 360 - Guide to Character Behavior 英文高清PDF下载 阅读1869次,点赞0次
- Modern OpenGL - GLSL着色语言3:GLSL中的数据类型 阅读2201次,点赞0次
- TensorRT - 使用Polygraphy工具比较onnx模型和TensorRT模型的推理结果是否一致 阅读1184次,点赞1次
- 资源分享 - Game Physics (Second Edition) 英文高清PDF下载 阅读2489次,点赞1次
- WordPress - wp_registration_url函数详解 阅读1200次,点赞0次
- WordPress - 站点底部显示站点运行时间 阅读4968次,点赞2次
- 资源分享 - Practical Linear Algebra - A Geometry Toolbox , Third Edition 英文高清PDF下载 阅读1412次,点赞0次
- 资源分享 - GPU Computing Gems, Emerald Edition 英文高清PDF下载 阅读1618次,点赞0次
- C++ - const_cast, static_cast, dynamic_cast, reinterpret_cast四种cast转换的区别和使用 阅读103次,点赞0次
评论
169