C | atexit函数

C | atexit函数

欢迎关注公众号“三戒纪元”

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
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值