Linux 下一个程序从执行到退出经历了什么?

发布时间 - 2026-01-26 00:00:00    点击率:
程序在Linux下执行到退出本质是内核接管其生命周期的过程:经execve()加载ELF、状态切换(R/S/D/Z)、exit()或_exit()清理、内核最终回收PID与资源。

一个程序在 Linux 下从执行到退出,本质是内核接管用户态进程生命周期的过程。它不是“直接运行代码”,而是经过一系列受控的内核介入步骤——跳过任意一环,程序根本启动不了。

execve() 系统调用才是真正起点

你以为 ./a.out 是程序自己开始跑?其实是 shell 调用了 execve(),把控制权彻底交给内核。这个调用会:

  • 清空当前进程的用户空间内存(栈、堆、代码段、数据段)
  • 按 ELF 文件头和 program header 加载新程序的代码段(.text)、初始化数据段(.data)、未初始化数据段(.bss
  • 设置新的栈帧,把 argcargvenvp 压入栈顶
  • 跳转到入口点(通

    常是 _start,不是 main

没成功返回 execve() 就意味着程序压根没“出生”——常见错误如 Permission denied(缺少执行权限或 noexec 挂载)、No such file or directory(动态链接器路径不对,哪怕文件存在也会报这个)。

内核如何管理进程状态切换

execve() 返回后,进程就进入 R(Running/Runnable)状态,但实际执行还取决于调度器。整个生命周期中,它会在以下状态间切换:

  • R:正在 CPU 上运行,或排在运行队列里等调度
  • S:可中断睡眠(比如等 read() 从磁盘读完)
  • D:不可中断睡眠(通常卡在底层驱动,如坏磁盘 IO,kill -9 也杀不掉)
  • Z:僵尸态——子进程已退出,但父进程还没调用 waitpid() 回收其退出码和资源

注意:ps 看到的 T(stopped)不是退出,而是被信号暂停(如 Ctrl+Zkill -STOP),仍占 PID 和内存资源。

exit() 和 _exit() 的区别决定资源清理方式

程序退出时,C 库封装了 exit(),但它和系统调用 _exit() 行为不同:

  • exit():先刷新所有 stdio 缓冲区(fflush(NULL)),调用 atexit() 注册的函数,最后才调用 _exit()
  • _exit():直接触发 sys_exit 系统调用,不刷缓存、不执行清理函数

在 fork 后的子进程中,如果用 exit() 可能导致父进程 stdio 缓冲区被重复写入(因为 fork 复制了缓冲区内容);这时应无条件用 _exit()。glibc 的 main() 返回其实隐式调用了 exit(),不是 _exit()

内核回收进程的最后一步:释放 PID 和资源

当进程调用 _exit() 或收到终止信号(如 SIGKILL),内核会:

  • 释放虚拟内存区域(VMA)、页表、打开的文件描述符(close_on_exec 位生效)、信号处理上下文
  • 向父进程发送 SIGCHLD,并把退出状态存进进程描述符(task_struct
  • 若父进程已退出,init 进程(PID 1)自动成为其父进程,并最终调用 waitid() 回收,避免僵尸累积

真正难排查的是:父进程忘了 wait(),又没设 SIGCHLD handler,或者 handler 里没调用 waitpid(-1, &status, WNOHANG) ——这时 ps aux | grep ' Z ' 就能看到一堆 Z 状态进程,它们不占内存,但 PID 被永久占用,直到父进程退出。


# linux  # 虚拟内存  #   # ai  # 区别  # NULL  # 封装  # Directory  #   # 会报  # 的是  # 加载  # 还没  # 就能  # 会在  # 但它  # 排在  # 后才  # 装了 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 专业企业网站设计制作公司,如何理解商贸企业的统一配送和分销网络建设?  Laravel请求验证怎么写_Laravel Validator自定义表单验证规则教程  消息称 OpenAI 正研发的神秘硬件设备或为智能笔,富士康代工  新三国志曹操传主线渭水交兵攻略  javascript基本数据类型及类型检测常用方法小结  制作电商网页,电商供应链怎么做?  Android利用动画实现背景逐渐变暗  INTERNET浏览器怎样恢复关闭标签页_INTERNET浏览器标签恢复快捷键与方法【指南】  Android Socket接口实现即时通讯实例代码  jQuery中的100个技巧汇总  Laravel怎么实现一对多关联查询_Laravel Eloquent模型关系定义与预加载【实战】  如何在万网自助建站中设置域名及备案?  Win11怎么关闭透明效果_Windows11辅助功能视觉效果设置  lovemo网页版地址 lovemo官网手机登录  如何快速生成橙子建站落地页链接?  软银砸40亿美元收购DigitalBridge 强化AI资料中心布局  动图在线制作网站有哪些,滑动动图图集怎么做?  Laravel怎么实现模型属性的自动加密  如何挑选最适合建站的高性能VPS主机?  Laravel如何优雅地处理服务层_在Laravel中使用Service层和Repository层  C#如何调用原生C++ COM对象详解  DeepSeek是免费使用的吗 DeepSeek收费模式与Pro版本功能详解  在线制作视频网站免费,都有哪些好的动漫网站?  Python文本处理实践_日志清洗解析【指导】  如何用免费手机建站系统零基础打造专业网站?  北京的网站制作公司有哪些,哪个视频网站最好?  如何用PHP快速搭建CMS系统?  Midjourney怎样加参数调细节_Midjourney参数调整技巧【指南】  用yum安装MySQLdb模块的步骤方法  Laravel如何实现数据导出到CSV文件_Laravel原生流式输出大数据量CSV【方案】  Laravel如何实现多对多模型关联?(Eloquent教程)  Laravel如何发送邮件_Laravel Mailables构建与发送邮件的简明教程  如何获取PHP WAP自助建站系统源码?  如何在 React 中条件性地遍历数组并渲染元素  如何使用 jQuery 正确渲染 Instagram 风格的标签列表  Laravel事件和监听器如何实现_Laravel Events & Listeners解耦应用的实战教程  Laravel如何使用.env文件管理环境变量?(最佳实践)  Laravel如何配置Horizon来管理队列?(安装和使用)  悟空识字如何进行跟读录音_悟空识字开启麦克风权限与录音  Python自然语言搜索引擎项目教程_倒排索引查询优化案例  绝密ChatGPT指令:手把手教你生成HR无法拒绝的求职信  如何获取免费开源的自助建站系统源码?  java ZXing生成二维码及条码实例分享  如何在阿里云虚拟服务器快速搭建网站?  Laravel怎么防止CSRF攻击_Laravel CSRF保护中间件原理与实践  使用豆包 AI 辅助进行简单网页 HTML 结构设计  如何制作新型网站程序文件,新型止水鱼鳞网要拆除吗?  学生网站制作软件,一个12岁的学生写小说,应该去什么样的网站?  实例解析Array和String方法  制作ppt免费网站有哪些,有哪些比较好的ppt模板下载网站?