什么是Linux上的僵尸进程?

时间:2020-01-09 10:45:47  来源:igfitidea点击:

如果我们是Linux用户,则我们可能已经看到僵尸进程在进程列表中出现混乱。我们无法杀死僵尸进程,因为它已经像真正的僵尸一样已经死亡。

僵尸基本上是尚未正确清理的死进程的剩余部分。创建僵尸进程的程序未正确编程,因此无法让僵尸进程陷入困境。

什么是僵尸进程?

要了解僵尸进程是什么以及导致僵尸进程出现的原因,我们需要对进程在Linux上的工作方式有所了解。

当一个进程在Linux上死掉时,它的所有进程描述符都不会立即从内存中删除(进程描述符只占用很少的内存)。进程状态变为EXIT_ZOMBIE,并使用SIGCHLD信号通知进程父进程其子进程已死亡。然后,父进程应该执行wait()系统调用,以读取死进程的退出状态和其他信息。这允许父进程从无效进程中获取信息。调用wait()之后,僵尸进程将从内存中完全删除。

这通常很快发生,因此我们不会看到僵尸进程在系统上堆积。但是,如果父进程的编程不正确,并且从不调用wait(),则其僵尸子进程将一直停留在内存中,直到将其清除为止。

诸如GNOME System Monitor,top命令和ps命令之类的实用程序会显示僵尸进程。

僵尸进程的危险

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

但是,尽管有一些僵尸进程确实表明系统上的父进程存在错误,但这些僵尸进程没有问题。

摆脱僵尸进程

我们无法杀死僵尸进程,因为我们可以杀死具有SIGKILL信号的僵尸进程已死亡的正常进程。请记住,除非系统上有大量僵尸,否则不需要摆脱僵尸进程。但是,有几种方法可以摆脱僵尸进程。

一种方法是通过将SIGCHLD信号发送到父进程。该信号告诉父进程执行wait()系统调用并清理其僵尸子进程。使用kill命令发送信号,将以下命令中的pid替换为父进程PID:

kill -s SIGCHLD pid

但是,如果父进程未正确编程,并且忽略了SIGCHLD信号,则将无济于事。我们必须杀死或者关闭僵尸父进程。当创建僵尸的进程结束时,init会继承僵尸进程并成为其新父进程。 (init是在Linux上启动时启动的第一个进程,并被分配了PID1. )init定期执行wait()系统调用以清理其僵尸子级,因此init会使僵尸工作很短。我们可以在关闭父进程后重新启动它。

如果父进程继续创建僵尸,则应对其进行修复,以使其正确调用wait()来获得其僵尸子进程。如果系统上的程序不断创建僵尸,请提交错误报告。