防止线程在处理异常后在分离时调用std :: terminate() [英] Preventing thread from calling std::terminate() on detach after handled exception

查看:561
本文介绍了防止线程在处理异常后在分离时调用std :: terminate()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have my own thread class that is intended to help safely manage exceptions. It looks like this: (skipped other constructors and mutexes for simplicity)

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::thread::~thread()中分离线程时std::terminate()被调用.如何防止系统这样做?

When thread throws exception it gets catched in catch(...) and saved to exc, everything is fine. But when execution goes further std::terminate is called just like exception wasn't caught. I also tried to pause the child thread (e.g Sleep(INFINITE)) after catching an exception but std::terminate() gets called while detaching the thread in std::thread::~thread() during stack unwinding in main thread. How can I prevent system of doing this?

平台:MSVC

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

推荐答案

您必须在破坏线程之前显式加入线程,这有助于防止在破坏线程之前忘记中断线程(在我使用过的每个实现都在std :: terminate消息中进行了说明.

You have to explicitly join a thread before destructing it, this is to help to prevent potential deadlocks/crashes when you forget to interrupt a thread before destroying it (in every implementation I've used this is stated in the std::terminate message).

这篇关于防止线程在处理异常后在分离时调用std :: terminate()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆