什么是Linux上的“僵尸进程”?

zombie processes on linux

如果你是一个Linux用户,你可能已经看到僵尸进程在你的进程列表周围。 你不能杀死一个僵尸进程,因为它已经死了 - 像一个实际的僵尸。

僵尸基本上是没有被正确清理的死过程的剩余位。 创建僵尸进程的程序没有正确编程 - 程序不应该让僵尸进程坚持。

图片来源: 丹尼尔·霍利斯特在Flickr上 (混音)

什么是僵尸进程?

要理解僵尸进程是什么,什么导致僵尸进程出现,您需要了解一下进程如何在Linux上工作。

当进程在Linux上死机时,并不是立即从内存中删除 - 进程描述符保留在内存中(进程描述符只占用很少的内存)。 进程的状态变为EXIT_ZOMBIE,并通知进程的父进程的子进程已经死于SIGCHLD信号。 然后,父进程应执行wait()系统调用,以读取死进程的退出状态和其他信息。 这允许父进程从死进程中获取信息。 wait()被调用后,僵尸进程被完全从内存中删除。

这通常发生非常快,所以你不会看到僵尸进程积累在您的系统上。 然而,如果一个父进程没有正确编程,从来没有调用wait(),它的僵尸孩子会坚持在内存中,直到他们被清理。

公用事业像GNOME系统监视器, 靠前指挥,和ps命令显示僵尸进程。

image

僵尸进程的危险

Zombie进程不会占用任何系统资源。 (实际上,每个僵尸进程都使用非常少量的系统内存来存储其进程描述符。)然而,每个僵尸进程保留其进程ID(PID)。 Linux系统具有有限数量的进程ID - 在32位系统上默认为32767。 如果僵尸以非常快的速率累积 - 例如,如果不正确编程的服务器软件在负载下创建僵尸进程 - 整个可用PID池将最终分配给僵尸进程,阻止其他进程启动。

然而,几个僵尸进程挂在周围没有问题 - 虽然他们表明一个错误与他们的父进程在您的系统上。

image

获取僵尸进程

你不能杀死僵尸进程,因为你可以杀死正常进程与SIGKILL信号 - 僵尸进程已经死了。 记住,你不需要摆脱僵尸进程,除非你有大量在你的系统 - 几个僵尸是无害的。 但是,有几种方法可以摆脱僵尸进程。

一种方法是通过向父进程发送SIGCHLD信号。 这个信号告诉父进程执行wait()系统调用并清理它的僵尸孩子。 发送与kill命令的信号,在下面的父进程的PID命令替换PID:

kill -s SIGCHLD pid

然而,如果父进程没有正确编程并忽略SIGCHLD信号,这将无济于事。 你必须杀死或关闭僵尸的父进程。 当创建僵尸的进程结束时,init继承僵尸进程并成为他们的新父进程。 (init是在启动时在Linux上启动的第一个进程,并且分配了PID 1)。init定期执行wait()系统调用来清理其僵尸孩子,因此init会使僵尸做短工作。 您可以在关闭父进程后重新启动它。

如果父进程继续创建僵尸,它应该是固定的,以便它适当地调用wait()来收获其僵尸孩子。 如果系统上的程序持续创建僵尸,请提交错误报告。

赞 (0)
分享到:更多 ()