C | atexit函数
文章目录
- C | atexit函数
- atexit
- 区别
- 进程终止的方式
- Reference
欢迎关注公众号“三戒纪元”
atexit
main函数是整个程序的入口,但是其实可以在内核中可以使用链接器来设置程序的开始地方。
当内核使用⼀个exec函数执行C程序时,在调⽤main函数之前先调用⼀个特殊的启动例程,可执行程序将此例程指定为程序的起始地址。
启动例程从内核获取命令行参数和环境变量,然后为调用main函数做好准备。
atexit函数是一个特殊的函数,它是在正常程序退出时调用的函数,叫为登记函数:
/* Register a function to be called when `exit' is called. */
extern int atexit (void (*__func) (void)) __THROW __nonnull ((1));
终⽌处理函数:⼀个进程可以登记若干个函数,这些函数由exit自动调用, atexit函数可以登记这些函数。
exit
调用终止处理函数的顺序和atexit登记的顺序相反,与参数压栈顺序有关。
区别
exit()
和_exit()
以及_Exit()
函数的本质区别是是否立即进入内核,_exit()
以及_Exit()
函数都是在调用后立即进入内核,而不会执行一些清理处理,但是exit()
则会执行一些清理处理,这也是为什么会存在atexit()
函数的原因,这些终止处理函数实际上就是完成各种所谓的清除操作的实际执行体。
比如有些指针在程序完成时才需要释放,但是程序什么时候结束,并不清楚。
这时候可以先在主函数中等级要清理或者释放的函数,然后等到程序结束时,自行调用即可。
#include <stdlib.h>
#include <iostream>void func1() { std::cout << "1 Call func1" << std::endl; }
void func2() { std::cout << "2 Call func2" << std::endl; }
void func3() { std::cout << "3 Call func3" << std::endl; }
int main() {std::cout << "start" << std::endl;atexit(func1);atexit(func2);atexit(func3);std::cout << "end" << std::endl;
// exit(0);return 0;
}
结果:
start
end
3 Call func3
2 Call func2
1 Call func1
如果不调用等级函数,那使用指针就要使用RAII类型的智能指针,就能解决这个问题。
进程终止的方式
进程终止的方式有8种,前5种为正常终止,后3种为异常终止:
1 从main函数返回;
2 调⽤exit函数;
3 调⽤_exit
或_Exit
;
4 最后⼀个线程从启动例程返回;
5 最后⼀个线程调⽤pthread_exit;
6 调⽤abort函数;
7 接到⼀个信号并终⽌;
8 最后⼀个线程对取消请求做出响应。
Reference
- https://blog.csdn.net/leex_brave/article/details/51813962