5. 进程终止

终止过程

一旦进程创建了,它是如何结束的呢?进程的终止是进程生命周期中的一个关键部分,它确保了系统资源的有效管理。

进程通常通过调用 _exit 系统调用来终止。此操作向内核发出信号,表明进程已完成,其资源(如内存和文件描述符)可以被回收。退出时,进程会向内核提供一个终止状态,这是一个整数值。按照惯例,状态 0 表示成功执行,而非零值表示发生错误。

然而,调用 _exit 并不会立即清除进程。父进程必须使用 wait 系统调用来确认其子进程的终止。此调用允许父进程检索子进程的终止状态。这种两步机制对于正确的进程清理至关重要。另一种 linux kill child process(终止子进程)的方式是使用信号,这是我们将在后续课程中探讨的主题。

孤儿进程 (Orphan Processes)

如果父进程在其子进程终止之前就终止了,会发生什么?子进程就成了“孤儿”。由于其原始父进程无法再调用 wait,内核会介入。孤儿进程会立即被一个特殊的系统进程(通常是 init,进程 ID 为 1)收养,该进程被认为是所有进程的祖先。然后 init 进程承担起父进程的角色,定期调用 wait 来收集其所有被收养子进程的终止状态,使它们能够干净地终止。

僵尸进程 (Zombie Processes)

当子进程终止,但其父进程尚未调用 wait 时,会发生不同的情况。在这种状态下,子进程就成了“僵尸”进程。内核会释放僵尸进程的大部分资源,但它会在进程表中保留一个条目。该条目包含进程 ID 和终止状态,等待父进程来收集。

僵尸进程已经死亡,因此它们不消耗 CPU 时间。你无法使用信号来终止它们,因为它们没有在运行。父进程调用 wait 来清理僵尸进程的过程称为“回收”(reaping)。如果父进程从不调用 wait,这些僵尸进程就会积累。虽然少量无害,但大量僵尸进程会填满进程表,阻止新进程的创建。在父进程也终止的情况下,init 会收养并回收僵尸进程。

僵尸进程 vs 孤儿进程

理解 zombie vs orphan process(僵尸进程与孤儿进程的对比)之间的区别,是诊断进程相关问题的关键。

  • 孤儿进程 是一个活动的、正在运行的进程,其父进程已经死亡。它被 init 收养并继续执行,直到它自己完成。
  • 僵尸进程 是一个已死的进程,它已经完成了执行,但在进程表中仍有一个条目。它正在等待其父进程读取其退出状态。

简而言之,孤儿是“活着但没有父母”,而僵尸是“死了但尚未被父进程完全回收”。

登录以保存您的学习进度

登录

练习

为了应用这些概念,请尝试以下实践实验:

  1. 管理和监控 Linux 进程 - 练习与前台和后台进程的交互,使用 ps 检查它们,使用 top 监控资源,使用 renice 调整优先级,以及使用 kill 终止它们。该实验提供了关于进程生命周期的实际经验,包括如何终止它们和观察它们的状态。

测验

进程成功完成的最常见终止状态是什么?