C++中哪个函数保证在突然终止或退出时被调用,可以执行清理活动..
根据"abrupt termination"的具体含义,有几种不同的选择:
main
返回或调用exit()
)时将调用全局析构函数。atexit()
注册一个函数,在正常终止时被调用。std::set_terminate
注册一个函数,当抛出但未捕获异常或因其他原因需要"终止异常处理"时调用。sigaction()
注册函数,在程序接收到信号时调用,其中许多信号通常会突然终止您的程序。 当程序处于内部不一致状态时,可能会调用信号处理程序,因此它们的功能非常有限。例如,它们不能执行任何可能分配内存的操作。此外,此API在Windows上不可用;有相应的替代品,但我不熟悉它们。SIGKILL
),你无法为其注册处理程序。这是一种特性,而不是错误。你作为用户需要一种方法来关闭一个进程,即使它已经尽力使自己无法被摧毁。此外,当用户的宠物兔子咬断电脑的电源线时,任何代码都无法保护您的进程。因此,设计程序以从崩溃中恢复可能是更好的选择,而不是在崩溃发生时尝试清理。有关此内容,请参阅 "crash-only design" 的文章。在这里阅读关于atexit
的内容:http://www.cplusplus.com/reference/clibrary/cstdlib/atexit/。然而,并不是所有情况下都会调用它(例如,调用abort
时不会触发您使用atexit
注册的函数)。
您可以实现自己的信号处理程序,将所有信号传递到那里,并为每个信号执行任何操作。
abort()
强制程序异常退出,或者 _Exit()
强制程序正常退出但绕过退出处理程序。但是,从主函数返回或调用 exit()
将运行退出处理程序。 - David Hammenset_terminate()
。
http://www.cplusplus.com/reference/std/exception/set_terminate/
同一个头文件中还有其他类似的函数,可用于补充情境。
int main()
{
try
{
// all your code here
}
catch(...)
{
// cleanup
}
return 0;
}
没有一个函数能够捕获所有的情况并且在所有的平台上都能运行。如果你需要在Windows上使用,你将必须处理SEH(Structured exception handling)异常。你需要定义和设置各种场景下的处理程序(SEH、C++异常、SIGABRT、Terminate等),执行共同的清理代码。查看zack在此处有关处理SIGABRT信号的回复。
对于SEH,你可以添加一个SE转换器来处理SE异常,并将它们转换为C++异常,请参考_set_se_translator以获取有关如何处理SEH异常的更多信息。
你可以参考设置terminate处理程序的文档和设置unexpected处理程序的好参考。
你将不得不编写自己的处理程序来处理每个场景。
最后,我建议使用一些现有的库来实现这个目的,我喜欢crashrprt。你熟悉信号处理吗?我建议你先学习它,然后再回来提出相关问题。看起来有几个人已经提到了它,但这是一个很好的资源可以参考:
编写自己的信号处理程序可以让您确定在捕获特定信号时要执行的操作。正如所述,有些信号无法被覆盖,这是有充分理由的。您不想让某人覆盖 kill -9,仅仅因为可能会创建一个不可能终止的程序。然而,像直接 kill 信号或者 ctrl-c、ctrl-d 等信号可以被捕获并按照您选择的方式进行处理。