C | atexit函数

2023-09-22 12:16:29

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
更多推荐

SpringBoot整合Activiti7——代理/候选人/候选组(四)

文章目录一、代理人二、候选人三、候选组四、组任务办理流程五、UEL表达式UEL-valueUEL-methodUELmethod结合value一、代理人一个用户任务只允许有一个代理人。为一个任务分配代理人后act_ru_task表的ASSIGNEE_字段会被设置为响应的值。审批任务设置assignee变量,表示是该任务

GaussDB技术解读系列:性能调优

近日,在第14届中国数据库技术大会(DTCC2023)的GaussDB“五高两易”核心技术,给世界一个更优选择专场,华为数据库技术专家李士福详细解读了GaussDB性能调优的相关技术和应用实践。本篇为大家分享GaussDB性能调优的实践。主要包括三个部分,分别是性能调优的整体介绍,性能调优的关键技术,性能调优的应用实践

5.14 Set Feature Command

5.14SetFeatureCommandSetFeatureCommand规定了Feature的属性。SetFeatureCommand使用datapointer,CommandDword10,CommandDword11,CommandDword12,CommandDword13,CommandDword14和Co

B : DS顺序表--连续操作

Description建立顺序表的类,属性包括:数组、实际长度、最大长度(设定为1000)该类具有以下成员函数:构造函数:实现顺序表的初始化。插入多个数据的multiinsert(inti,intn,intitem[])函数,实现在第i个位置,连续插入来自数组item的n个数据,即从位置i开始插入多个数据。删除多个数据

vue3+element项目创建

一、创建vue3项目步骤要创建一个Vue3+ElementUI的项目,你可以按照以下步骤进行操作:1.确保你已经安装了Node.js和npm(Node.js的包管理器)。你可以在命令行中运行以下命令来检查它们是否已经安装:node-vnpm-v2.使用VueCLI来创建一个新的Vue项目。在命令行中运行以下命令:npm

一花落,万物生,AIGC为国货复兴注入新活力

在最近的商业新闻中,国货们发“花难财”的热度持续在涨,“花西子”曾经是中国国货的代表之一,以其独特的美妆产品而闻名于世。然而,近期因为李佳琦“79块钱哪里贵了”事件的原因,让不少网友扒出这支79的眉笔算下来一克竟要比黄金还贵,加上主播的出言嘲讽消费者,让大家纷纷开始抵制这个产品。“花西子”翻车之后,国货品牌在一夜之间占

【湖科大教书匠】计算机网络随堂笔记第1章(计算机网络概述)

目录1.1、计算机网络在信息时代的作用我国互联网发展状况1.2、因特网概述1、网络、互连网(互联网)和因特网2、因特网发展的三个阶段因特网服务提供者ISP(InternetServiceProvider)基于ISP的三层结构的因特网3、因特网的标准化工作4、因特网的组成边缘部分核心部分C/S和P2P:客户-服务器方式:

android 逆向去广告工具和流程

主要用到的软件:1、安卓修改大师:有很多功能,但有会员限制。好用的是字符查找后,可以在smali和java切换2、apktool:反编译、回编译工具。但是是命令行方式3、jadx-gui-1.4.7-no-jre-win反编译成java,非常好用4、AndroidKiller_v1.3.1:反编译有些不正常,签名后,在

SpringMVC

目录SpringMVC体系结构SpringMVC配置注解@Controller@RequestMapping@RequestParam@RequestBody@SessionAttributes@DateTimeFormat@ResponseBodySpringMVC体系结构(1)首先浏览器发送请求——>Dispatc

Linux的调试工具 - gdb(超详细)

Linux的调试工具-gdb1.背景2.开始使用指令的使用都用下面这个C语言简单小代码来进行演示:1.list或l行号:显示文件源代码,接着上次的位置往下列,每次列10行。2.list或l函数名:列出某个函数的源代码。3.r或run:运行程序。4.break或b行号:在某一行设置断点5.n或next:单条执行(类似vs

RK3568驱动指南|第五篇 中断-第42章 软中断实验

瑞芯微RK3568芯片是一款定位中高端的通用型SOC,采用22nm制程工艺,搭载一颗四核Cortex-A55处理器和MaliG522EE图形处理器。RK3568支持4K解码和1080P编码,支持SATA/PCIE/USB3.0外围接口。RK3568内置独立NPU,可用于轻量级人工智能应用。RK3568支持安卓11和li

热文推荐