[C++] 退出清理函数解读(exit、_exit、abort、atexit)
说明:在C++中,exit、_exit(或_Exit)、abort和atexit是用于控制程序退出和清理的标准库函数。下面是对这些函数的详细解读:
exit
- 函数原型:
void exit(int status); - 作用:
exit函数用于正常退出程序。它会传递给操作系统一个退出状态码,通常用于指示程序成功完成(返回0)或发生错误(返回非0值)。 - 清理操作:
exit会调用所有注册的atexit回调函数,这些函数按照注册的逆序执行,用于进行资源清理和释放。 - 线程效应:调用
exit会导致程序立即终止,所有线程都会被立即停止。
_exit 或 _Exit
- 函数原型:
void _exit(int status); - 作用:
_exit(或_Exit,具体名称取决于平台)用于立即退出程序,与exit不同,它不会执行任何清理操作。 - 特点:这个函数不会调用
atexit注册的回调函数,也不会调用对象的析构函数,因此用于需要立即终止程序的情况。 - 线程效应:与
exit相同,_exit会导致所有线程立即停止。
abort
- 函数原型:
void abort(void); - 作用:
abort函数用于异常退出程序,通常在捕获到严重错误时使用。它会导致程序立即终止,并且不会执行任何清理操作。 - 信号:
abort会向操作系统发送SIGABRT信号,这可能导致操作系统生成核心转储(core dump),以供后续分析。 - 线程效应:
abort会终止整个程序,包括所有线程。
atexit
- 函数原型:
int atexit(void (*func)(void)); - 作用:
atexit用于注册一个函数,该函数将在程序调用exit退出时被调用。这些函数按照注册的逆序执行。 - 返回值:如果注册成功,返回0;如果注册失败(例如,因为达到注册函数的数量限制),返回非0值。
- 限制:C++标准没有规定
atexit可以注册的最大函数数量,但编译器通常会有一个限制。
按照常规的了解,程序结束已经有return操作可以控制,那么为什么还要引入退出相关函数呢?我们来继续看👇。
1 为什么引入退出相关函数
C++中引入exit、_exit(或_Exit)、abort和atexit这些函数是为了提供灵活的程序退出机制,以满足不同的程序终止需求。除了退出控制状态,还有其他引入的原因:
-
资源清理:
exit在程序退出前会调用所有通过atexit注册的回调函数,这允许开发者执行必要的清理工作,如关闭文件、释放资源等,确保程序优雅地结束。 -
立即终止程序:
_exit或_Exit用于立即终止程序,不进行任何清理工作。这在需要快速退出程序,且不需要进行资源清理时非常有用。 -
异常退出:
abort用于异常退出程序,通常在捕获到严重错误且无法恢复时使用。abort会导致程序立即终止,并且通常会生成核心转储(core dump),供开发者分析程序崩溃的原因。 -
注册退出回调:
atexit允许开发者注册一个或多个回调函数,这些函数将在程序正常退出时被调用,从而执行必要的清理工作。 -
兼容性:
exit和atexit是从C语言继承而来的,它们在C++中得以保留,以确保与C代码的兼容性。 -
处理未捕获的异常:当程序中发生未捕获的异常时,C++的异常处理机制会调用
std::terminate,该函数默认行为是调用abort,但可以通过set_terminate函数自定义退出行为。 -
多线程环境下的退出:在多线程程序中,可能需要在某个线程捕获异常后立即安全地退出整个程序,
abort可以满足这一需求。
通过提供这些不同的退出函数,C++允许开发者根据程序的特定需求和上下文选择最合适的退出策略。
2 退出相关函数使用详解
以下是atexit、exit、_exit和abort 这四个函数在不同场景下的示例代码。
2.1 atexit的使用示例
atexit的使用示例,代码实现如下:
#include <cstdlib>
#include <iostream>void cleanupResources() {std::cout << "Cleaning up resources in atexit function." << std::endl;
}void closeFiles() {std::cout << "Closing files in atexit function." << std::endl;
}int main() {// 注册退出时的回调函数std::atexit(closeFiles);std::atexit(cleanupResources);std::cout << "Program is running." << std::endl;// 执行一些操作...// 当程序退出时,closeFiles 和 cleanupResources 将被调用return 0; // 正常退出程序
}
2.2 exit的使用示例
exit的使用示例,代码实现如下:
#include <cstdlib>
#include <iostream>void cleanup() {std::cout << "Cleaning up resources." << std::endl;
}int main() {std::atexit(cleanup); // 注册退出时的回调函数std::cout << "Program is running." << std::endl;// 执行一些操作...std::exit(EXIT_SUCCESS); // 正常退出程序return 0; // 这行代码不会被执行
}
2.3 _exit的使用示例
_exit的使用示例,代码实现如下:
#include <cstdlib>
#include <iostream>int main() {std::cout << "Program is running." << std::endl;// 执行一些操作..._exit(EXIT_SUCCESS); // 立即退出程序,不执行任何清理// 以下代码不会被执行std::cout << "This will not be printed." << std::endl;return 0;
}
注意:此时即便是有atexit的注册函数,也不会执行。
2.4 abort的使用示例
abort的使用示例,代码实现如下:
#include <cstdlib>
#include <iostream>
#include <stdexcept>int main() {try {// 模拟一个错误条件bool errorCondition = true;if (errorCondition) {throw std::runtime_error("A serious error occurred!");}} catch (const std::runtime_error& e) {std::cerr << "Caught an exception: " << e.what() << std::endl;std::abort(); // 异常退出,会生成核心转储}return 0; // 这行代码不会被执行
}
在这些示例中,exit和atexit通常用于正常的程序退出流程,其中exit是显式退出程序,而atexit用于注册退出时需要调用的回调函数。_exit用于立即退出程序,不执行任何清理操作,通常用于紧急情况。abort用于异常退出,通常在捕获到不可恢复的错误时使用,它可能会导致操作系统生成核心转储文件。
相关文章:
[C++] 退出清理函数解读(exit、_exit、abort、atexit)
说明:在C中,exit、_exit(或_Exit)、abort和atexit是用于控制程序退出和清理的标准库函数。下面是对这些函数的详细解读: exit 函数原型:void exit(int status);作用:exit函数用于正常退出程序…...
代码随想录(回溯)
组合(Leetcode77) 思路 用递归每次遍历从1-n得数,然后list来记录是不是组合到k个了,然后这个每次for循环的开始不能和上一个值的开始重复,所以设置个遍历开始索引startindex class Solution {static List<List<…...
编译原理1
NFA&DFA 在正规式的等价证明可以借助正规集,也可以通过有限自动机DFA来证明等价,以下例题是针对DFA证明正规式的等价,主要步骤是①NFA;②状态转换表; ③状态转换矩阵; ④化简DFA; 文法和语…...
【信息系统项目管理师知识点速记】组织通用管理:流程管理
23.2 流程管理 通过流程视角能够真正看清楚组织系统的本质与内在联系,理顺流程能够理顺整个组织系统。流程是组织运行体系的框架基础,流程框架的质量影响和决定了整个组织运行体系的质量。把流程作为组织运行体系的主线,配备满足流程运作需要的资源,并构建与流程框架相匹配…...
前端 JS 经典:箭头函数的意义
箭头函数是为了消除函数的二义性。 1. 二义性 函数的二义性指函数有不同的两种用法,就造成了二义性,函数的两种用法:1. 指令序列。2. 构造器 1.1 指令序列 就是调用函数,相当于将函数内部的代码再从头执行一次。 1.2 构造器 …...
Java List操作详解及常用方法
Java List操作详解及常用方法 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿! 什么是Java List? Java中的List是一种动态数组,它允许存…...
《mysql篇》--查询(进阶)
目录 将查询结果作为插入数据 聚合查询 聚合函数 count sum group by子句 having 联合查询 笛卡尔积 多表查询 join..on实现多表查询 内连接 外连接 自连接 子查询 合并查询 将查询结果作为插入数据 Insert into 表2 select * from 表1//将表1的查询数据插入…...
数据库-MySQL 实战项目——书店图书进销存管理系统数据库设计与实现(附源码)
一、前言 该项目非常适合MySQL入门学习的小伙伴,博主提供了源码、数据和一些查询语句,供大家学习和参考,代码和表设计有什么不恰当还请各位大佬多多指点。 所需环境 MySQL可视化工具:navicat; 数据库:MySq…...
eNSP中WLAN的配置和使用
一、基础配置 1.拓扑图 2.VLAN和IP配置 a.R1 <Huawei>system-view [Huawei]sysname R1 GigabitEthernet 0/0/0 [R1-GigabitEthernet0/0/0]ip address 200.200.200.200 24 b.S1 <Huawei>system-view [Huawei]sysname S1 [S1]vlan 100 [S1-vlan100]vlan 1…...
<sa8650>QCX ID16_UsecaseRawLiteAuto 使用详解
<sa8650>QCX ID16_UsecaseRawLiteAuto 使用详解 一、前言二、ID16_UsecaseRawLiteAuto拓扑图三、UsecaseRawLiteAuto拓扑图 解析3.1 camxUsecaseRawLiteAuto.xml3.2 camxRawLiteAuto.xml四、测试一、前言 我们在使用QCX时,如果由于使用的摄像头自带了ISP,那么可能不需要使…...
为什么3d重制变换模型会变形?---模大狮模型网
在当今数字技术飞速发展的时代,3D建模和动画制作已经成为影视、游戏和虚拟现实中不可或缺的一部分。然而,即使在高级的3D软件中,重制(rigging)和变换(transformation)过程中仍然会面临一个普遍的问题——模型变形。这种变形可能导致动画效果不…...
ElasticSearch中的BM25算法实现原理及应用分析
文章目录 一、引言二、BM25算法实现原理BM25算法的实现原理1. 词频(TF):2. 逆文档频率(IDF):3. 长度归一化:4. BM25评分公式: BM25算法示例 三、BM25算法在ElasticSearch中的应用分析…...
web权限到系统权限 内网学习第一天 权限提升 使用手工还是cs???msf可以不??
现在开始学习内网的相关的知识了,我们在拿下web权限过后,我们要看自己拿下的是什么权限,可能是普通的用户权限,这个连添加用户都不可以,这个时候我们就要进行权限提升操作了。 权限提升这点与我们后门进行内网渗透是乘…...
ros1仿真导航机器人 hector_mapping gmapping
仅为学习记录和一些自己的思考,不具有参考意义。 1 hector_mapping 建图过程 (1)gazebo仿真 roslaunch why_simulation why_slam.launch <launch><!-- We resume the logic in empty_world.launch, changing only the name of t…...
嵌入式实验---实验五 串口数据接收实验
一、实验目的 1、掌握STM32F103串口数据接收程序设计流程; 2、熟悉STM32固件库的基本使用。 二、实验原理 1、STM32F103R6能通过查询中断方式接收数据,每接收到一个字节,立即向对方发送一个相同内容的字节,并把该字节的十六进…...
ubuntu 22.04下编译安装glog共享库
笔者是完美主义者,在编译opencv4.9时,有个有关glog的warn,就下载编译google的glog库并把它编译成shared libaray。重新编译opencv4.9时,该warn解除。现把编译安装glog过程记录,以备后查。 以下操作全程以root身份或sudo执行。 cd…...
Linux环境安装配置nginx服务流程
Linux环境的Centos、麒麟、统信操作系统安装配置nginx服务流程操作: 1、官网下载 下载地址 或者通过命令下载 wget http://nginx.org/download/nginx-1.20.2.tar.gz 2、上传到指定的服务器并解压 tar -zxvf nginx-1.20.1.tar.gzcd nginx-1.20.1 3、编译并安装到…...
设计模式-模板模式
简介 模板方法模式是一种行为设计模式,它在父类中定义了一个操作的算法框架,允许子类在不改变算法结构的情况下重定义算法的某些步骤。这种模式是基于继承的,通过抽象类将通用的代码抽取到超类中,同时通过具体类实现或者改写算法…...
物理删除和逻辑删除区别
物理删除和逻辑删除是数据库管理中针对记录删除操作的两种不同方式,它们的主要区别在于数据的实际处理和后续影响: 物理删除: 操作实质:物理删除会将数据记录从数据库表中彻底移除,包括记录所占的磁盘空间都会被释放。…...
C# 警告 warning MSB3884: 无法找到规则集文件“MinimumRecommendedRules.ruleset”
警告 warning MSB3884: 无法找到规则集文件“MinimumRecommendedRules.ruleset” C:\Program Files\Microsoft Visual Studio\2022\Professional\MSBuild\Current\Bin\amd64\Microsoft.CSharp.CurrentVersion.targets(129,9): warning MSB3884: 无法找到规则集文件“MinimumRe…...
利用最小二乘法找圆心和半径
#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...
GruntJS-前端自动化任务运行器从入门到实战
Grunt 完全指南:从入门到实战 一、Grunt 是什么? Grunt是一个基于 Node.js 的前端自动化任务运行器,主要用于自动化执行项目开发中重复性高的任务,例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...
STM32HAL库USART源代码解析及应用
STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...
Golang——7、包与接口详解
包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…...
django blank 与 null的区别
1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是,要注意以下几点: Django的表单验证与null无关:null参数控制的是数据库层面字段是否可以为NULL,而blank参数控制的是Django表单验证时字…...
Java详解LeetCode 热题 100(26):LeetCode 142. 环形链表 II(Linked List Cycle II)详解
文章目录 1. 题目描述1.1 链表节点定义 2. 理解题目2.1 问题可视化2.2 核心挑战 3. 解法一:HashSet 标记访问法3.1 算法思路3.2 Java代码实现3.3 详细执行过程演示3.4 执行结果示例3.5 复杂度分析3.6 优缺点分析 4. 解法二:Floyd 快慢指针法(…...
npm安装electron下载太慢,导致报错
npm安装electron下载太慢,导致报错 背景 想学习electron框架做个桌面应用,卡在了安装依赖(无语了)。。。一开始以为node版本或者npm版本太低问题,调整版本后还是报错。偶尔执行install命令后,可以开始下载…...
