提问人:Vero 提问时间:1/15/2023 更新时间:1/15/2023 访问量:45
使用 proram STOP 在多线程上下文中抛出清除异常
Throwing Clear Exception in a Multithreaded Context with a proram STOP
问:
我有一个程序,它抛出另一个线程,如下所示:
#include <iostream>
#include <stdexcept>
#include <thread>
void op()
{
std::cout << "OP HELLO WORLD" << std::endl;
throw(std::runtime_error("OP ERROR"));
};
int main(int argc, char* argv[])
{
//throw(std::runtime_error("MAIN ERROR"));
std::thread t(op);
t.join();
std::cout << "MAIN HELLO WORLD" << std::endl;
};
我希望我的程序打印一条清晰的错误消息并停止。我知道我可以使用 or ,但是错误消息不清楚,并且不包含日志“OP ERROR”。std::abort
std::terminate
你能帮我编写一个程序,当失败时,它会退出并记录一条明确的错误消息。 当我尝试 , 块时也不起作用?std::future
try
catch
答:
2赞
sklott
1/15/2023
#1
你在寻找这样的东西吗?
#include <iostream>
#include <stdexcept>
#include <thread>
#include <future>
void op()
{
std::cout << "OP HELLO WORLD" << std::endl;
throw(std::runtime_error("OP ERROR. File: " __FILE__ ", Line: "+ std::to_string(__LINE__)));
};
int main(int argc, char* argv[])
{
//throw(std::runtime_error("MAIN ERROR"));
auto res = std::async(op);
try {
res.get();
} catch(const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
return -1;
}
std::cout << "MAIN HELLO WORLD" << std::endl;
}
如果要输出所有线程的错误而不将异常返回到主线程,则可以设置自己的 .terminate()
#include <iostream>
#include <cstdlib>
#include <exception>
#include <thread>
void op()
{
std::cout << "OP HELLO WORLD" << std::endl;
throw(std::runtime_error("OP ERROR"));
}
void my_terminate()
{
auto eptr = std::current_exception();
try {
if (eptr) {
std::rethrow_exception(eptr);
}
} catch(const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
std::abort();
}
int main(int argc, char* argv[])
{
std::set_terminate(my_terminate);
//throw(std::runtime_error("MAIN ERROR"));
std::thread t(op);
t.join();
std::cout << "MAIN HELLO WORLD" << std::endl;
}
出于某种原因,MSVC 使用每个线程的处理程序,要使其正常工作,您需要单独调用每个线程。set_termnate()
评论
0赞
Vero
1/15/2023
非常感谢。我正在寻找一些可以扔进工作线程而不是:)之外的东西再次感谢。但我认为从问题来看,这就是答案。我应该指定抛入工作线程并从工作线程停止程序。
1赞
rustyx
1/15/2023
#2
为避免调用 ,请确保异常不会在线程函数外部“泄漏”。std::terminate
void op()
{
try {
std::cout << "OP HELLO WORLD" << std::endl;
throw std::runtime_error("OP ERROR");
} catch (const std::exception& e) {
std::cerr << "Exception: " << e.what() << std::endl;
exit(1);
}
}
如果要自动查看异常的文件和行号,在 C++ 中通常是不可能的。
如果要在主线程中的单个位置捕获所有异常,则需要捕获它们并将它们传递给主线程。有一个有用的包装实用程序 std::p ackaged_task
,它给出一个未来,您可以在其中等待结果或异常。
#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[])
{
try {
std::packaged_task<void()> task{&op};
auto result = task.get_future();
std::thread t{std::move(task)};
t.join();
result.get();
std::cout << "MAIN HELLO WORLD" << std::endl;
} catch (const std::exception& e) {
std::cerr << "Exception: " << e.what() << std::endl;
}
}
评论
std::terminate
std::terminate
std::future