多线程环境下抛出清晰异常并终止程序的实现求助
捕获子线程异常并输出指定错误信息
子线程中未捕获的异常会直接触发std::terminate,无法在主线程中捕获处理。要实现捕获子线程异常并输出"OP ERROR"后终止程序,可以通过std::packaged_task或std::promise将子线程的异常传递到主线程处理,以下是两种可行实现:
方法一:使用std::packaged_task自动传递异常
std::packaged_task会自动捕获任务执行过程中的异常,并将其存储到关联的std::future中,主线程通过future.get()可以重新抛出该异常,进而捕获处理。
#include <iostream> #include <stdexcept> #include <thread> #include <future> void op() { std::cout << "OP HELLO WORLD" << std::endl; throw(std::runtime_error("OP ERROR")); }; int main(int argc, char* argv[]) { std::packaged_task<void()> task(op); std::future<void> fut = task.get_future(); std::thread t(std::move(task)); t.join(); // 等待子线程执行完成 try { fut.get(); // 若子线程抛出异常,此处会重新抛出 } catch (const std::runtime_error& e) { std::cerr << "错误信息: " << e.what() << std::endl; std::terminate(); // 终止程序,或直接return 1; } std::cout << "MAIN HELLO WORLD" << std::endl; return 0; };
方法二:使用std::promise手动传递异常指针
通过std::promise和std::exception_ptr手动捕获子线程的异常,并传递到主线程重新抛出处理,这种方式更灵活,允许在子线程中对异常做额外处理后再传递。
#include <iostream> #include <stdexcept> #include <thread> #include <future> void op(std::promise<std::exception_ptr>& prom) { try { std::cout << "OP HELLO WORLD" << std::endl; throw(std::runtime_error("OP ERROR")); } catch (...) { // 捕获所有异常,将异常指针存入promise prom.set_exception(std::current_exception()); } }; int main(int argc, char* argv[]) { std::promise<std::exception_ptr> prom; std::future<std::exception_ptr> fut = prom.get_future(); std::thread t(op, std::ref(prom)); t.join(); std::exception_ptr eptr = fut.get(); if (eptr) { try { std::rethrow_exception(eptr); // 重新抛出异常 } catch (const std::runtime_error& e) { std::cerr << "错误信息: " << e.what() << std::endl; std::terminate(); } } std::cout << "MAIN HELLO WORLD" << std::endl; return 0; };
两种方法都能实现需求:子线程抛出异常后,主线程捕获并输出包含"OP ERROR"的错误信息,随后终止程序。
内容的提问来源于stack exchange,提问作者Vero
相关产品推荐
相关产品推荐

