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
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
评论
50