Linux 进程退出exit(函数)

一、进程退出两大类

1. 正常退出(主动自杀,进程主动结束自身)

进程主动执行退出逻辑,自行结束生命周期,主要分为三种方式:main函数return、标准库exit()、系统调用_exit()。

1)main 函数 return
  • main 的 return n 等价于调用 exit(n)。

  • 普通函数里的 return 只是函数返回,不会结束进程。

  • 只有 main 函数的 return 会触发完整进程退出流程:结束进程、刷新 IO 缓冲区、回收进程资源。

2)库函数 exit() 标准库退出

头文件:#include <stdlib.h>

cs 复制代码
void exit(int status);
  • status :进程退出码,标识退出状态。0 代表正常退出,非 0 代表异常退出,可由父进程 wait() 获取。

  • 执行流程(带完整用户层清理):

    • 刷新标准 IO 缓冲区,将 printf、文件缓存数据落盘或输出到终端;

    • 调用 atexit() 注册的退出钩子函数;

    • 最终调用底层系统调用 _exit(),由内核真正终止进程。

3)系统调用 _exit() 直接内核终止

头文件:#include <unistd.h>

cs 复制代码
void _exit(int status);
  • 直接进入内核销毁进程,完全跳过用户层清理工作;

  • 不刷新 IO 缓冲区、不执行 atexit 回调;

  • 缓冲区未落地数据直接丢失,会出现 printf 无打印现象。

关键示例对比

示例 1:_exit 丢失缓存,无打印
cs 复制代码
#include <stdio.h>
#include <unistd.h>
int main()
{
    printf("hello world"); // 数据存在缓冲区,未换行不刷新
    _exit(0);
    return 0;
}

运行结果:终端无任何输出

示例 2:exit 自动刷新缓存,正常打印
cs 复制代码
#include <stdio.h>
#include <stdlib.h>
int main()
{
    printf("hello world");
    exit(0);
    return 0;
}

运行结果:终端输出 hello world

补充小知识点

如果 printf 末尾加换行 \n,标准行缓冲会强制刷新,此时 _exit 也能正常打印内容:

cs 复制代码
printf("hello world\n"); 
_exit(0); // 能正常输出,换行触发缓冲区刷新

2. 非正常退出(被动他杀,外部 / 异常强制终止)

进程没有主动调用任何退出函数,由程序异常或外部信号干涉,被强制杀死。分为两类场景:

1)程序运行异常崩溃
  • 段错误 SIGSEGV:访问非法内存、空指针、数组越界

  • 总线错误 SIGBUS:非法地址对齐访问、访问无效硬件地址

  • 浮点错误 SIGFPE:除数为 0、浮点运算溢出

2)外部发送终止信号
  • kill 进程PID:发送 SIGTERM 温柔杀死,进程可捕获信号、执行收尾工作

  • kill -9 进程PID:发送 SIGKILL 强制杀死,进程无法捕获、无法清理,内核直接销毁进程


二、exit / _exit / main return 核心差异表

方式 刷新 IO 缓冲区 执行 atexit 钩子 层级
main 函数 return 是 执行 用户层封装
exit() 是 执行 标准库函数
_exit() 否 不执行 系统调用

三、拓展补充考点

  1. 退出码取值规则 :退出码仅低 8 位有效,有效范围 0~255,父进程通过 **wait/waitpid**获取退出状态。

  2. 缓冲区本质 :printf 是标准库封装,数据存放在用户态缓冲区;_exit 直接进入内核销毁进程,丢弃用户态缓存;exit 在调用内核接口前主动刷新缓冲区。

  3. fork 子进程场景 :子进程结束推荐使用 _exit,避免刷新父子共享的缓冲区,造成数据重复输出、日志错乱问题。

相关推荐
李游Leo1 小时前
HarmonyOS 7 TaskPool + Node-API + zstd:Native 批量压缩任务的主线程隔离、进度回传与资源收口【鸿蒙心迹】
java·华为·harmonyos
Cx330❀1 小时前
【Qt 进阶指南】详解 Qt 常用标准对话框与主窗口组件架构
开发语言·qt·ui·性能优化·架构·图形渲染
Light Gao1 小时前
Encoder 与 Decoder 详解:从 Embedding 到 Seq2Seq 的完整数据流
java·开发语言·embedding
HZZD_HZZD1 小时前
弱网下CoAP还省吗?合众致达Cat.1电表90天实测:MQTT重连流量占52%、续航差距从38%拉大到73%
开发语言·物联网·php·腾讯云
web打印社区1 小时前
Windows 网页静默打印设置步骤:客户端、防火墙与联调清单
开发语言·前端·javascript·chrome·pdf·ecmascript
小师兄吃牛肉1 小时前
什么是R语言?如何快速学习R语言
开发语言·学习·r语言
All for pursuit.1 小时前
【回溯-2】22.括号生成
数据结构·c++·算法·leetcode
程序猿乐锅1 小时前
【黑马点评 | 第十一篇】关注 Feed 流实现
java·数据库·redis·分布式·后端·缓存·maven
longlongzihan1 小时前
LeetCode 1004.最大连续1的个数III 滑动窗口及动态规划题解
c++·算法·leetcode·dp·滑动窗口