c++ - 线程中的异常

标签 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 有人可以解释一下线程中的异常是如何工作的吗?

最佳答案

根据 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/

相关文章:

iphone - 如何更新 UI 以显示 Core Data 长时间运行的进程?

c++ - 对不同变量的 vector 使用排序功能

c++ - Code::Blocks 无法识别 std::thread

c++ - constexpr 函数中的编译时类型生成

c++ - 将 vec4[idx[i]] * scalar[i] 与 YMM vector 寄存器相加

c++ - 从 max 函数返回 Stepanov Notes

ios - reloadData 不会将完成处理程序的 dispatch_async 中的 TableView 重新加载到主线程

c++ - 转换基类的双指针

Java多线程处理一个字段

c++ - 为什么 emplace_back 需要移动构造函数