如果在产卵后引发异常则未捕获 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 中并创建其实例而不是创建原始线程。在析构函数中,可以检查线程是否仍然可连接,并在可能的情况下执行操作以优雅地停止线程体。在这种情况下,当抛出异常时,析构函数将在线程仍处于 运行 时被调用,它将解决问题。