我有自己的线程类,旨在帮助安全地管理异常。看起来像这样:(为简单起见,跳过了其他构造函数和互斥对象)
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] 删除。
我来说两句