Linux中的atexit函数

来源:互联网 发布:淘宝联盟官方发单助手 编辑:程序博客网 时间:2024/04/28 07:01

什么是atexit函数?

起初学习C语言的时候,我们都知道整个程序的入口是main函数,但是其实事实并不是如此,在内核中可以使用链接器来设置程序的开始地方。当内核使用一个exec函数执行C程序时,在调用main函数之前先调用一个特殊的启动例程,可执行程序将此例程指定为程序的其实地址。启动历程从内核获取命令行参数和环境变量,然后为main函数做好准备。

Atexit简介

函数名: atexit头文件:#include<stdlib.h>功 能: 注册终止函数(即main执行结束后调用的函数)用 法: void atexit(void (*func)(void));注意:exit调用这些注册函数的顺序与它们 登记时候的顺序相反。同一个函数如若登记多次,则也会被调用多次。

一个进程可以登记若干个(至少32个)个函数,这些函数由exit自动调用,这些函数被称为终止处理函数, atexit函数可以登记这些函数。 exit调用终止处理函数的顺序和atexit登记的顺序相反(网上很多说造成顺序相反的原因是参数压栈造成的,参数的压栈是先进后出,和函数的栈帧相同),如果一个函数被多次登记,也会被多次调用。

进程的终止方式

进程终⽌的⽅式有8种,前5种为正常终⽌它们是:
1:从 main 返回
2:调用 exit
3:调用 _exit 或 _Exit
4:最后一个线程从其启动例程返回
5:最后一个线程调用pthread_exit
异常终止有3种,它们是:
6:调用 abort
7:接到一个信号并终止
8:最后一个线程对取消请求做出响应

exit()和_exit()以及_Exit()函数的本质区别是是否立即进入内核,_exit()以及_Exit()函数都是在调用后立即进入内核,而不会执行一些清理处理,但是exit()则会执行一些清理处理,这也是为什么会存在atexit()函数的原因,因为exit()函数需要执行清理处理,需要执行一系列的操作,这些终止处理函数实际上就是完成各种所谓的清除操作的实际执行体。

验证atexit函数的调用顺和退出顺序
eg:

#include<stdio.h>  #include<stdlib.h>  void fun1()  {      printf("The first...\n");  }  void fun2()  {      printf("The second...\n");  }  void fun3(){    printf("The third....\n");}void fun4()  {      printf("The finall...\n");  }  int main()  {      atexit(fun1);      atexit(fun2);      atexit(fun3);     atexit(fun4);     exit(0);  }  

运行结果:

这里写图片描述

大家会发现atexit函数的调用顺序和登记顺序是相反的。
atexit函数的用途也是比较广泛的:可以按照你予设的顺序摧毁全局变量(类),例如有个log类,你在其它的全局类里也有可能调用到Log类写日志。所以log 类必须最后被析构 。假如没有规定析构顺序,那么程序在退出时将有可能首先析构log类,那么其它的全局类在此时将无法正确写日志。 把数据写回文件, 删除临时文件, 这才是真正有用的。

0 0
原创粉丝点击