std::atexit
- 注册 func 所指向的函数,使得在正常程序中止(通过 std::exit() 或从 main 函数返回)时调用它。
- 可以多次注册同一函数
- 保证实现支持注册至少 32 个函数。准确限制是实现定义的。
- 若函数通过异常退出,则调用 std::terminate 。
- atexit 是线程安全的:从数个线程调用函数不引入数据竞争。
#include <iostream>
#include <cstdlib>
void atexit_handler_1()
{
std::cout << "at exit #1\n";
}
void atexit_handler_2()
{
std::cout << "at exit #2\n";
}
int main()
{
const int result_1 = std::atexit(atexit_handler_1);
const int result_2 = std::atexit(atexit_handler_2);
if ((result_1 != 0) || (result_2 != 0)) {
std::cerr << "Registration failed\n";
return EXIT_FAILURE;
}
std::cout << "returning from main\n";
return EXIT_SUCCESS;
}
std::exit
导致正常程序终止发生
#include <iostream>
#include <cstdlib>
class Static {
public:
~Static()
{
std::cout << "Static dtor\n";
}
};
class Local {
public:
~Local()
{
std::cout << "Local dtor\n";
}
};
Static static_variable; // *将*调用此对象的析构函数
void atexit_handler()
{
std::cout << "atexit handler\n";
}
int main()
{
Local local_variable; // // 将*不*调用此对象的析构函数
const int result = std::atexit(atexit_handler); // 将调用处理函数
if (result != 0) {
std::cerr << "atexit registration failed\n";
return EXIT_FAILURE;
}
std::cout << "test\n";
std::exit(EXIT_SUCCESS);
}
std::abort
#include <iostream>
#include <csignal>
#include <cstdlib>
class Tester{
public:
Tester(){std::cout << "Tester contruction\n";}
~Tester(){std::cout << "Tester dectruction\n";}
};
Tester static_tester; // 不调用析构函数
void signal_handler(int signal){
if(signal == SIGABRT){
std::cerr << "SIGABRT received\n";
}else{
std::cerr << "Unexpected signal " << signal << " received\n";
}
std::_Exit(EXIT_FAILURE);
}
int main() {
Tester automatic_tester; // 不调用析构函数
// 安装处理函数
auto previous_handler = std::signal(SIGABRT, signal_handler);
if (previous_handler == SIG_ERR) {
std::cerr << "Setup failed\n";
return EXIT_FAILURE;
}
std::abort(); // 引发 SIGABRT
std::cout << "This code is unreachable\n";
}