进程终止
100%

进程 · 第 5 课

进程终止

学习退出状态、等待、僵尸进程和重新指定父进程如何完成 Linux 进程生命周期。

进程可以通过从 main 函数返回、调用退出接口,或被信号终止而结束。内核会释放其大多数资源,但父子进程计量会继续,直到父进程收集终止信息。

退出状态

正常退出的程序会提供一个整数状态。按惯例,状态 0 表示成功,非零值表示某种失败或其他结果。非零值的确切含义属于程序接口。

在 shell 中,可以这样检查最近一个前台管道的状态:

$ command
$ printf '%s\n' "$?"

Shell 只公开范围有限的编码状态,也会表示信号终止,因此该值不是完整的诊断记录。程序应记录自己的退出代码。

按照 Unix 惯例,哪个正常退出状态表示成功?

等待和回收

内核会记录子进程如何终止,并通知其父进程。父进程使用 wait() 系统调用族中的成员取回该信息。收集这条记录称为回收。

等待也可以协调执行:shell 会等待前台命令完成后再显示提示符,而对于后台作业则可以推迟等待。设计良好的长期运行父进程必须安排回收子进程,同时不阻塞无关工作。

成功的 wait 操作让父进程取回什么?

僵尸进程

子进程退出后、终止记录被回收前,它会显示为僵尸进程,在 ps 中通常是状态 Z。它不再执行,也不保留普通地址空间,但最小的进程表条目和计量信息仍然存在。

向僵尸进程发送信号不能让它再次退出。如果僵尸持续积累,应诊断未执行 wait 的父进程,通过适当运维流程重启或修正该父进程,或让僵尸重新指定给会回收它的进程。大量僵尸可能耗尽 PID 或进程表容量。

哪个描述符合僵尸进程?

孤儿进程和重新指定父进程

父进程退出而子进程仍在运行时,内核会把该子进程重新指定给适当的 subreaper,或相关 PID 命名空间中的 init 进程。子进程可能正在运行、休眠、停止,或之后成为僵尸;“孤儿”描述的是失去原父进程关系,而不是某种执行状态。

收养进程会负责收集终止状态。现代服务管理器和容器环境意味着不能假设新父进程始终是主机的 PID 1。

进程比原父进程存活得更久时会发生什么?

课程已完成

你已完成 进程终止

现在,你可以区分执行结束与父进程侧清理。

  • 把零解释为惯例上的成功,并按程序文档解释非零状态。

  • 使用等待收集子进程的终止信息。

  • 把僵尸进程识别为已退出但尚未回收。

  • 把孤儿进程识别为原父进程退出后被重新指定父进程的子进程。

保存学习进度

创建免费账户即可保存本课进度,并在任意设备上继续学习。

创建免费账户
下一节
返回 进程