如果在产生std :: thread之后引发异常,则不会捕获异常

时间:2017-08-20 14:22:00

标签: c++ multithreading exception-handling stdthread

我对异常的奇怪行为感到困惑,这些异常在产生另一个线程后会在主线程中抛出:

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 );

比正常捕捉:

  

错误!

为什么在第一种情况下没有发现异常?我应该怎么做以通常的方式来抓住它?

2 个答案:

答案 0 :(得分:3)

抛出异常时,线程对象将被销毁。但是线程析构函数将在仍可连接时被调用。这会导致调用terminate,因此永远不会调用异常处理程序。

在没有正确同步的情况下写入来自不同线程的标准流也不是一个好主意。

答案 1 :(得分:1)

好的,经过一些研究后我发现了这个问题的解决方案。必须将线程包装到类中并创建其实例,而不是创建原始线程。在析构函数中,可以检查线程是否仍然可以连接,并执行操作以尽可能优雅地停止线程体。在这种情况下抛出异常时,将在线程仍在运行时调用析构函数,它将对事物进行排序。