[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…...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...
Objective-C常用命名规范总结
【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...

使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...
LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》
这段 Python 代码是一个完整的 知识库数据库操作模块,用于对本地知识库系统中的知识库进行增删改查(CRUD)操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 📘 一、整体功能概述 该模块…...

接口自动化测试:HttpRunner基础
相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具,支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议,涵盖接口测试、性能测试、数字体验监测等测试类型…...

【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)
前言: 双亲委派机制对于面试这块来说非常重要,在实际开发中也是经常遇见需要打破双亲委派的需求,今天我们一起来探索一下什么是双亲委派机制,在此之前我们先介绍一下类的加载器。 目录 编辑 前言: 类加载器 1. …...