如果在产卵后引发异常则未捕获 std::thread
Exception not caught if raised after spawning std::thread
我对异常的奇怪行为感到困惑,异常是在生成另一个线程后在主线程中抛出的:
void thread_body(){
while(true) cout << "in thread" << endl;
}
int main(int argc, char** argv)
{
try{
auto t = std::thread( thread_body );
throw std::runtime_error("error!");
t.join();
} catch (const std::exception& e) {
cout << e.what() << endl;
}
}
输出为:
in thread
in thread
in thread
terminate called without an active exception
The program has unexpectedly finished.
如果我像这样在生成线程之前抛出:
throw std::runtime_error("error!");
auto t = std::thread( thread_body );
比正常捕获:
error!
为什么第一种情况没有捕获到异常?我应该怎么做才能正常捕捉它?
当抛出异常时线程对象将被销毁。但是线程析构函数将在它仍然可连接时被调用。这会导致调用 terminate
,因此永远不会调用异常处理程序。
在没有适当同步的情况下从不同线程写入标准流也不是一个好主意。
好的,经过一些研究我找到了这个问题的解决方案。必须将线程包装到 class 中并创建其实例而不是创建原始线程。在析构函数中,可以检查线程是否仍然可连接,并在可能的情况下执行操作以优雅地停止线程体。在这种情况下,当抛出异常时,析构函数将在线程仍处于 运行 时被调用,它将解决问题。
我对异常的奇怪行为感到困惑,异常是在生成另一个线程后在主线程中抛出的:
void thread_body(){
while(true) cout << "in thread" << endl;
}
int main(int argc, char** argv)
{
try{
auto t = std::thread( thread_body );
throw std::runtime_error("error!");
t.join();
} catch (const std::exception& e) {
cout << e.what() << endl;
}
}
输出为:
in thread in thread in thread terminate called without an active exception The program has unexpectedly finished.
如果我像这样在生成线程之前抛出:
throw std::runtime_error("error!");
auto t = std::thread( thread_body );
比正常捕获:
error!
为什么第一种情况没有捕获到异常?我应该怎么做才能正常捕捉它?
当抛出异常时线程对象将被销毁。但是线程析构函数将在它仍然可连接时被调用。这会导致调用 terminate
,因此永远不会调用异常处理程序。
在没有适当同步的情况下从不同线程写入标准流也不是一个好主意。
好的,经过一些研究我找到了这个问题的解决方案。必须将线程包装到 class 中并创建其实例而不是创建原始线程。在析构函数中,可以检查线程是否仍然可连接,并在可能的情况下执行操作以优雅地停止线程体。在这种情况下,当抛出异常时,析构函数将在线程仍处于 运行 时被调用,它将解决问题。