exit() 函数和 _exit() 函数

简介: exit() 函数和 _exit() 函数

exit() 函数和 _exit() 函数都是用来终止进程的。当程序执行到 exit() 函数或 _exit() 函数时,进程会无条件地停止剩下的所有操作,清除各种数据结构,并终止本进程的运行。但是,这两个函数仍然有一些本质的区别,如下图所示:

微信截图_20221209152107.png


从上图可以看出, _exit() 函数的作用是直接使进程停止运行,清除其使用的内存空间,并清除其在内核中的各种数据结构; exit() 函数则在这些基础上做了一些包装,在执行退出之前加了若干道工序。 exit() 函数与 _exit() 函数最大的区别就在于 exit() 函数在终止当前进程之前要检查该进程打开了那些文件,并把文件缓存区中的内容写回文件,即上图所示的“刷新I/O缓存区”。


Linux 的标准库函数中,有一种被称为“缓存I/O(buffered I/O)”操作,其特征就是对应每一个打开的文件,在内存中都有一片缓存区。


每次读文件时,会连续读出若干条记录,这样在下次读文件时就可以直接从内存的缓存区中读取;同样,每次写文件的时候,也仅仅时写入内存中的缓存区,等满足了一定的条件(如缓存区满)时,再将缓存区中的内容一次性写入文件。


这种技术大大增加了文件读写的速度,但也给编程带来了一些麻烦。比如有些数据,认为已经被写入文件了,实际上因为没有满足特定的条件,它们还只是保存在缓存区中,这时用 _exit() 函数直接将进程关闭,缓存区中的数据就会丢失。因此,若想保证数据的完整性,最好使用 exit() 函数。

#include <stdlib.h>
void exit(int status);
#include <unistd.h>
void _exit(int status);点击复制复制失败已复制


示例

通过简单的示例,展示两个函数的区别,如下所示:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, const char *argv[]) {
  printf("exit before...");
  _exit(0);
  printf("exit after...");
  return 0;
}点击复制复制失败已复制


编译并运行之后会发现没有任何输出。原因是 printf() 作为标准输出函数,在没有换行符刷新时,执行输出打印到缓存区中,然后调用调用 _exit() 函数,将程序退出,缓存区中的数据就会丢失。


如果将 _exit() 函数换成 exit() 函数,则结果完全不同:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, const char *argv[]) {
  printf("exit before...");
  exit(0);
  printf("exit after...");
  return 0;
}点击复制复制失败已复制


编译并运行:

$ gcc main.c && ./a.out 
exit before...%   点击复制复制失败已复制


提示

两个代码都没有输出 "exit after..." ,说明两个函数都具有主动调用将进程退出的功能。


目录
相关文章
|
监控 Linux
Linux 进程标识符:深入探讨 getpid() 和 getppid()
在Linux操作系统中,进程管理是一项重要的任务。为了正确管理和监控进程,我们需要了解如何获取进程的标识符。本文将详细介绍两个重要的Linux系统调用函数:`getpid()`和`getppid()`。这两个函数用于获取当前进程的进程ID(PID)和父进程的PID。我们将深入探讨它们的用途、使用方法以及示例代码。
2784 0
|
JSON iOS开发 开发者
uniapp配置ios的Universal Link和associate domains
uniapp配置ios的Universal Link和associate domains
|
10月前
|
数据采集 数据挖掘 数据安全/隐私保护
4步教你用rvest抓取网页并保存为CSV文件
本文介绍如何使用R语言的`rvest`包抓取网页数据并保存为CSV文件,以界面新闻网站为例。通过设置代理IP(如亿牛云)、User-Agent和Cookie,增强访问稳定性和安全性。代码涵盖环境配置、数据抓取、解析及保存步骤,确保高效、稳定地获取网页数据。适用于数据分析和统计分析场景。
213 8
4步教你用rvest抓取网页并保存为CSV文件
|
SQL 存储 监控
SQL数据库安装指南:步骤详解与最佳实践
安装和配置SQL数据库可能是一个复杂的过程,但通过遵循本文提供的详细步骤和最佳实践,您可以确保数据库的成功安装和高效运行。无论您是初学者还是经验丰富的数据库管理员,掌握SQL数据库的安装和管理技能都是至关重要的。通过不断学习和实践,您将能够更好地利用SQL数据库来支持您的业务需求和数据分析工作。记住,定期维护和优化数据库是保证其长期性能和稳定性的关键。祝您在安装和配置SQL
|
12月前
|
人工智能
写歌词的技巧和方法:优化歌词结构的秘诀,妙笔生词AI智能写歌词软件
歌词是音乐的灵魂,优化其结构能让作品更加动人。掌握开头吸引人、主体结构清晰、情感递进自然及结尾余味悠长等技巧至关重要。同时,借助《妙笔生词智能写歌词软件》的多种AI功能,如智能写词、押韵优化等,可有效提升创作效率与质量,为你的歌词增添光彩。
|
安全 编译器 C++
【C/C++ 基础知识 】 C++ 初始化大全:选择最适合您需求的方式
【C/C++ 基础知识 】 C++ 初始化大全:选择最适合您需求的方式
303 2
|
测试技术 Linux Android开发
i2c总线及设备测试工具i2ctools:i2cdetect、i2cdump、i2cget、i2cset
本文介绍了i2ctools工具集的使用,包括i2cdetect、i2cdump、i2cget和i2cset,这些工具有助于I2C设备的开发和调试,通过检测设备、读写寄存器和数据块来提高开发效率。
2736 1
|
弹性计算 关系型数据库 Serverless
告别资源瓶颈,函数计算驱动多媒体文件处理方案:https://www.aliyun.com/solution/tech-solution/fc-drive-file
本文介绍了一种基于阿里云的一键部署解决方案,利用云服务器ECS、RDS MySQL、OSS、函数计算FC及MNS等服务,实现高效的多媒体文件处理。方案通过事件驱动机制,将文件处理任务解耦,并自动弹性扩展,按需付费,简化部署流程,提高处理效率。本文还提供了详细的部署步骤与体验反馈,展示了从配置到文件处理的全过程。
|
C++
c++ std::lock与std::scoped_lock底层实现原理源码剖析
std::lock用于同时获取多把锁(两把及两把以上)std::scoped_lock定义于c++ 17标准,是std::lock的RAII封装类以下代码纯来自msvc实现。
308 0
c++ std::lock与std::scoped_lock底层实现原理源码剖析
|
SQL 人工智能 分布式计算
MaxCompute 产品新能力发布-2024年Q1
随着阿里云MaxCompute4.0的产品新版本发布,越来越多的MaxCompute产品新能力被客户广泛关注,包括近实时查询/湖仓一体&开放架构/容灾备份等。在此我们对外整体介绍一下MaxCompute FY25-Q1产品新功能,帮助更多用户借此了解MaxCompute4.0云原生数仓新版本的重点产品特性,核心竞争力与典型用户场景等信息。
468 1