线程中的例外情况

时间:2014-10-04 04:35:20

标签: c++ multithreading c++11

如果抛出线程中的异常,如果该线程没有捕获到该异常,主线程会受到影响吗?

为什么呢?据我所知,异常是基于堆栈的,所以当一个发生时,堆栈会向右展开吗?但是如果一个线程有自己的堆栈,为什么主线程会受到影响?

示例:

#include <iostream>
#include <thread>
#include <chrono>

int main()
{
    std::thread([]{
        throw std::runtime_error("HELLO");
    }).detach();

    std::this_thread::sleep_for(std::chrono::seconds(5));
}

此线程已分离。我无法理解为什么主程序会崩溃。对我来说,这就像一个子进程崩溃并导致父进程崩溃..

:S有人可以解释线程中的异常是如何工作的吗?

1 个答案:

答案 0 :(得分:2)

根据MSDN(http://msdn.microsoft.com/en-us/library/ac9f67ah.aspx),如果找不到合适的catch处理程序,则将调用terminate函数。默认情况下,terminate会调用C运行时函数abort,但如果需要,可以通过调用set_terminate来覆盖它。

在多线程场景中,terminate将在此辅助线程中调用,这将导致程序退出 - 即您的主/父/条目线程将立即停止,并且您的进程将被操作系统杀死。 / p>

将线程与进程进行比较是不公平的 - 进程是彼此内存隔离的,而线程则不是。如果程序处于意外或不合需要的状态,这可能会引发异常,这意味着程序的内存空间中的数据可能已损坏,重要的是程序适当地处理异常,如果不是,则终止(以避免将损坏的数据写入磁盘的风险,这是一件非常糟糕的事情(TM)。我认为这解释了如果任何线程没有处理异常,那么拥有程序abort背后的动机,因为如果主线程继续执行它可能会对您不想要的损坏或无效数据进行操作。

这与其他platforms like C#中的内容相同(除了代替terminate,它的AppDomain.UnhandledException,并且可以恢复),尽管Java是一个值得注意的例外(否)在线程将终止但进程将继续运行的地方 - 我想(在Java的情况下警告:推测!)因为内存本身不会被破坏而在那里没有那么多的伤害即使应用程序对象状态可能已损坏,也允许进程继续。