如果被 pthread_create
调用的函数具有以下结构
try{
...code....
pthread_detach(pthread_self());
pthread_exit(NULL);
}catch(...){
std::cout<<"I am here"<<std::endl;
}
为什么在执行 pthread_exit
时,省略号的异常处理程序会被调用?
(请注意,例如 std::exception
不会被抛出)
如果被 pthread_create
调用的函数具有以下结构
try{
...code....
pthread_detach(pthread_self());
pthread_exit(NULL);
}catch(...){
std::cout<<"I am here"<<std::endl;
}
为什么在执行 pthread_exit
时,省略号的异常处理程序会被调用?
(请注意,例如 std::exception
不会被抛出)
至少在GCC中,pthread_exit
可能会抛出一个___forced_unwind异常,用于在线程退出期间展开堆栈。它不继承自std::exception
,因此不能像捕获标准异常一样捕获它。如果您确实捕获了该异常,请确保重新throw
它以便它能发挥作用:
try {
...
} catch (abi::___forced_unwind&) {
throw;
} catch (...) {
// whatever
}
抛出异常的原因是 pthread_exit
被指定为永远不会返回。让它抛出异常可以保证栈分配变量的清理,并且在其位置之后不执行任何代码(除非你捕获 unwind 异常...)。然而这种方法不太便携,例如 Clang 使用完全不同的机制。catch (...)
惯用法做的更多的是伤害而不是好处。它有时被用来"稳定"抛出未知异常的代码。但这只是把问题的可视性推迟到以后的时间和地点,使得很难确定问题的真正起源。在这样的 catch 中唯一合理的做法是进行最小限度的清理、可能的记录,然后重新抛出异常。由于未处理的异常导致进程崩溃并不好看,但它可以提供一个可调试的崩溃转储,清楚地显示了出错的命令。但这只是我的怨恨 catch (...)
,与 pthread_exit
几乎没有关系...abi::__forced_unwind exception
异常也可能在使用 pthread_cancel
取消的线程中抛出。在终止 pthreads 时要小心省略号 catch。 - Tanner Sansbury__force_unwind
很感兴趣,而且2012年的链接已经失效。 - Antoine