万圣节快乐,开源人士!
这是一个和 *epoch* 时间一样古老的故事。 自从有了 C 和 Unix,以及(后来)Linux 以来,我们就有了 *僵尸*。 具体来说,有些进程被标记为 *僵尸进程*。 一些人不理解,另一些人忽略,并且对于我们许多人试图`kill`这些进程的努力免疫,并且没有取得多大成功。 为什么会这样?
Linux 中的进程是什么?
这一切都始于 Linux 中的程序被执行时,当它执行时,它的运行实例被称为进程。 您可以使用 `ps` 命令在 Linux 环境中看到所有进程。
$ ps -ax
PID TTY STAT TIME COMMAND
1 ? Ss 0:01 /usr/lib/systemd/systemd rhgb --switched-root --sys
2 ? S 0:00 [kthreadd]
3 ? I< 0:00 [rcu_gp]
4 ? I< 0:00 [rcu_par_gp]
有时,一个进程启动另一个进程,使第一个进程成为第二个进程的父进程。 `pstree` 命令是一个很棒的工具,可让您查看系统上进程的“家谱”。
$ pstree -psn
systemd(1)─┬─systemd-journal(952)
├─systemd-udevd(963)
├─systemd-oomd(1137)
├─systemd-resolve(1138)
├─systemd-userdbd(1139)─┬─systemd-userwor(12707)
│ ├─systemd-userwor(12714)
│ └─systemd-userwor(12715)
├─auditd(1140)───{auditd}(1141)
├─dbus-broker-lau(1164)───dbus-broker(1165)
├─avahi-daemon(1166)───avahi-daemon(1196)
├─bluetoothd(1167)
每个进程都在系统中分配一个数字。 进程 ID 号 1 被分配给启动过程中执行的第一个进程,PID 1 之后的每个后续进程都是它的后代。 PID 1 进程是 *init*,在大多数较新版本的 Linux 上,它只是一个指向 `systemd` 程序的符号链接。
使用 kill 命令结束进程
您可以使用 `kill` * *命令在 Linux 系统中终止进程。 尽管名称如此,`kill` 命令和诸如 `pkill` 和 `killall` 等一系列命令被编写/设计为向一个或多个进程发送信号。 如果未指定,则它发送的默认信号是 SIGTERM 信号以终止该进程。
当父进程死亡或被杀死时,并且其子进程没有跟随其父进程的死亡,我们称该进程为 *孤儿进程*。
如何杀死僵尸进程
另一方面,僵尸进程无法被杀死! 为什么你可能会问? 好吧,因为它们已经死了!
每个子进程在终止时都会变成一个僵尸进程,然后被父进程移除。 当进程退出其存在并释放其使用的资源时,其名称仍在操作系统的进程表中。 然后,父进程的工作是从进程表中删除其名称。 如果失败,我们就有了一个僵尸进程,它实际上不再是一个进程,而只是操作系统进程表中的一个条目。
这就是为什么即使对已失效(僵尸)进程使用带有 `-9` (SIGKILL) 选项的 `kill` 命令也无效,因为没有什么可以杀死的。
因此,要杀死一个僵尸进程,即从进程列表(进程表)中删除它的名字,你必须杀死它的父进程。 例如,如果 PID 5878 是一个僵尸进程,并且它的父进程是 PID 4809,那么要杀死僵尸进程 (5878),你需要结束父进程 (4809)
$ sudo kill -9 4809 #4809 is the parent, not the zombie
关于僵尸进程,我的最后一句警告。 杀死父进程时要非常小心。 如果一个进程的父进程是 PID 1,并且你杀死了它,你将会重启你自己!
那将会是一个更可怕的故事!
评论已关闭。