处理异常后阻止线程在分离时调用 std::terminate()
Preventing thread from calling std::terminate() on detach after handled exception
我有自己的线程 class,旨在帮助安全地管理异常。它看起来像这样:(为简单起见,跳过了其他构造函数和互斥量)
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;
};
这个class的意思是像这样使用:
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
类似:How can I propagate exceptions between threads?
你必须在销毁它之前明确地加入一个线程,这有助于防止潜在的 deadlocks/crashes 当你忘记在销毁它之前中断一个线程(在我使用的每个实现中都说明了这一点std::terminate 消息)。
我有自己的线程 class,旨在帮助安全地管理异常。它看起来像这样:(为简单起见,跳过了其他构造函数和互斥量)
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;
};
这个class的意思是像这样使用:
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
类似:How can I propagate exceptions between threads?
你必须在销毁它之前明确地加入一个线程,这有助于防止潜在的 deadlocks/crashes 当你忘记在销毁它之前中断一个线程(在我使用的每个实现中都说明了这一点std::terminate 消息)。