如果线程中抛出异常,如果该线程中未捕获该异常,主线程是否会受到影响?
为什么?据我所知,异常是基于堆栈的,因此当发生异常时,堆栈就会展开,对吧?但如果一个线程有自己的堆栈,为什么主线程会受到影响呢?示例:
#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 有人可以解释一下线程中的异常是如何工作的吗?
最佳答案
根据 MSDN ( http://msdn.microsoft.com/en-us/library/ac9f67ah.aspx ),如果没有找到合适的 catch
处理程序,则将调用 terminate
函数。默认情况下,terminate
会调用 C 运行时函数 abort
,但如果需要,您可以通过调用 set_terminate
来覆盖此函数。
在多线程场景中,将在此辅助线程中调用 terminate
,这将导致您的程序退出 - 即您的主/父/入口线程将立即停止,并且您的进程将被终止操作系统。
将线程与进程进行比较是不公平的 - 进程之间是内存隔离的,而线程则不然。如果程序处于意外或不良状态,则可能会引发异常,这意味着程序内存空间中的数据可能会损坏,程序正确处理异常非常重要,如果没有,则终止(以避免写入损坏的风险)数据到磁盘,这是一件非常糟糕的事情(TM)。我认为这解释了如果任何线程不处理异常则程序中止
背后的动机,因为如果主线程继续执行它可能正在对损坏或无效的数据进行操作,这是您不希望看到的。
这与其他platforms like C#中的相同(除非它不是 terminate
,而是 AppDomain.UnhandledException
,并且是可恢复的),尽管 Java 是一个值得注意的异常(没有双关语),其中线程将终止,但进程将终止继续运行 - 我想(警告:推测!)在 Java 的情况下,因为内存本身不会被损坏,所以即使应用程序对象状态可能被损坏,允许进程继续也没有太大的危害。
关于c++ - 线程中的异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26189682/