我有一个函数,我想在程序退出时运行:
void foo() {
std::cout<< "Exiting" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
如何在程序存在的情况下将其注册为运行,无论它何时以及为什么退出 - 由于signal,exit()调用等?
Set*_*gie 31
您可以std::atexit在cstdlib标头中使用恰当命名的函数:
#include <cstdlib>
void exiting() {
std::cout << "Exiting";
}
int main() {
std::atexit(exiting);
}
Run Code Online (Sandbox Code Playgroud)
系统将维护一组注册的函数,atexit并在调用exit函数或程序返回时以相反的顺序调用它们main.您可以通过这种方式注册至少32个功能.
我是作为 Linux 用户回答的,但所有这些都应该适用于 Windows。
我有这个类似的问题,所以希望我可以总结以前的答案并加上我的两分钱。
信号和abort():^C和^Z能“截获”,退出退出之前打电话给你的功能,大概是()。信号SIGQUITAKA^\和SIGKILL不具有击键无法拦截。这是使用csignal标头和 C++ lambda的示例。
#include <iostream>
#include <csignal>
#include <cstdlib>
using namespace std;
int main()
{
//signal requires lam take an int parameter
//this parameter is equal to the signals value
auto lam =
[] (int i) { cout << "aborting" << endl; exit(0); };
//^C
signal(SIGINT, lam);
//abort()
signal(SIGABRT, lam);
//sent by "kill" command
signal(SIGTERM, lam);
//^Z
signal(SIGTSTP, lam);
while(1)
{
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
退出:因为我exit()在上面的例子中使用过,所以这里必须小心。如果正在运行的函数是一个只需要运行一次的清理函数,也许has_run可以使用静态变量。或者在上面的例子中,raise()一个你无法拦截的信号。但那些往往带有核心转储,感觉很脏。你的选择,在这里。一个例子如下
#include <cstdlib>
#include <iostream>
using namespace std;
int main()
{
//called with no parameters
auto lam = [] () { cout << "at exit"; };
atexit(lam);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
请注意,c++11 添加了 a quick_exit,它具有at_quick_exit与上面相同的伴随。但是quick_exit没有执行清理任务。相比之下,exit调用对象析构函数并关闭 C 流,只有自动存储变量没有被清理。