防止线程在处理异常后在分离时调用std :: terminate()

mfkw1

我有自己的线程类,旨在帮助安全地管理异常。看起来像这样:(为简单起见,跳过了其他构造函数和互斥对象)

class ExceptThread
    : public std::thread {
public:
    template<typename Func, typename... Args>
    ExceptThread(Func&& f, Args&&... args)
        : std::thread([] (Args&&... args) {
        try {
            return f(args...);
        } catch(...) {
            exc = std::current_exception();
        }
    }, args...) { }
    // skipped other constructors etc.
    //...    
    void check() { 
        if(exc) { 
            std::exception_ptr tmp = exc; 
            exc = nullptr; 
            std::rethrow_exception(tmp); 
        } 
    }

private:
    std::exception_ptr exc;
};

该类的用法如下:

ExceptThread et([] { std::this_thread::sleep_for(5s); throw std::runtime_error("Ugly exception"); });

try {
    while(/*...*/) {
        // main loop
        et.check();
    }
} catch(std::exception& e) {
    // do sth
}

问题:

当线程引发异常时,它将被捕获catch(...)并保存到中exc,一切都很好。但是,当执行进一步时,就会std::terminate被调用,就像未捕获到异常一样。我还尝试Sleep(INFINITE)在捕获异常后暂停子线程(例如),但在主线程中的堆栈展开期间std::terminate()分离线程时被调用std::thread::~thread()如何防止系统这样做?

平台:MSVC

相似:如何在线程之间传播异常?

艾伦·伯特尔斯

您必须在销毁线程之前显式加入线程,这有助于防止在销毁线程之前忘记中断线程的情况下潜在的死锁/崩溃(在我使用的每个实现中,此操作都在std :: terminate消息中进行了说明) 。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

libc ++ abi.dylib:terminate_handler意外引发异常-0堆栈跟踪iOS7 / iOS 8

JavaScript Web Worker-close()与Terminate()

从noexcept函数参数的构造函数引发的异常是否会立即导致对std :: terminate()的调用?

可能在调用`XCUIApplication()。terminate()`之后阻止XCode调用调试器。

编写死亡测试以验证std :: set_terminate行为

从类成员初始化程序引发的异常应该调用std :: terminate()吗?

Asyncio异常处理程序:直到事件循环线程停止后才被调用

throw()函数是否应始终在异常上展开堆栈并允许捕获异常或必须调用std :: terminate?

可见性受限的`noexcept`函数中的`std :: terminate`调用-GCC vs Clang Codegen

如果set_terminate中的处理程序不中止怎么办?

为什么调用shared_from_this会调用std :: terminate

DLL的std :: set_terminate吗?

调用join时如何解决`terminate被调用而没有活动异常'

如何将Std :: set_terminate与SetUnhandledExceptionFilter一起使用?

swbemobjectex类的幽灵/隐藏方法(例如.Terminate)

boto3中的terminate_instances()和terminate()有什么区别?

异常后的线程处理

处理Eclipse控制台上的Terminate按钮的单击?

在某些情况下,使用std :: set_terminate无法捕获C ++纯虚函数调用吗?

特定命令上的Console.Terminate事件

objProcess.Terminate 未找到

抛出异常后,何时调用 .net 核心异常过滤器?

Python 多处理中的 Process.terminate() 和 Process.kill() 有什么区别?

在 asyncio 子进程上调用 .terminate() 会引发 ProcessLookupError

AttributeError: 'NoneType' 对象没有属性 'terminate'

为什么在抛出我的析构函数时没有调用 std::terminate

我可以直接调用 std::terminate 吗?

当抛出前一个异常时从(创建/复制/移动)构造函数中抛出异常时,为什么不调用 std::terminate()?

std::terminate() 是否触发堆栈展开?