pthread_cancel
是通过类型 __cxxabi::__forced_unwind
的特殊异常实现的,因此当取消线程时,会引发异常并展开堆栈。因此,人们应该总是重新抛出由 catch (...)
捕获的异常,以免它成为 __forced_unwind
,吞噬它会遇到来自运行时的愤怒消息。
我的问题是,通过
__forced_unwind
然后 std::current_exception()
暂时包装 std::rethrow_exception()
是否安全,前提是我不吞下它。
代码中:
~~~
} catch (...) {
handleException();
}
// elsewhere
void handleException() {
try { std::rethrow_exception(std::current_exception()); }
catch (const std:exception &e) { log(e.what()); return; } // swallow
catch (...) { log("unknown exception caught"); throw; } // re-throw, could be __forced_unwind
}
这个定义明确吗?如果是这样,它在哪里定义为工作?
它的实现定义了是否有效。
__cxxabiv1::__forced_unwind
是一种抽象类型,具有私有析构函数,只能通过引用捕获。
namespace __cxxabiv1
{
/**
* @brief Thrown as part of forced unwinding.
* @ingroup exceptions
*
* A magic placeholder class that can be caught by reference to
* recognize forced unwinding.
*/
class __forced_unwind
{
virtual ~__forced_unwind() throw(); // private dtor
// Prevent catch by value.
virtual void __pure_dummy() = 0; // pure
};
}
std::current_exception
“捕获当前异常对象并创建一个std::exception_ptr
,其中包含副本或对该异常对象的引用(取决于实现)。”
如果您使用的实现需要副本,则编译将失败,因为它无法复制。如果没有,它只会保留对现有异常对象的引用,并且
std::rethrow_exception()
将像其他异常一样工作。
如果您一开始就捕获了异常,则上述内容成立。自 C++11 以来,已知
pthread_cancel
会导致 application 终止(但我不确定情况是否仍然如此)。
关于使用
pthread_cancel
,Jonathan Wakely 写道(https://gcc.gnu.org/legacy-ml/gcc-help/2015-08/msg00040.html):
...或者接受您不应在 C++11 中使用
。我不 有什么更好的建议,抱歉。pthread_cancel
即使该帖子中提到的问题现在已经得到解决,我仍然认为这个建议是合理的。永远不要使用
pthread_cancel
!通过设置线程正在检查线程可以以受控方式终止的位置的状态来取消线程。