在我的 Fedora Core 9 网络服务器上,内核为 2.6.18.8,init 不会回收僵尸进程。如果不是进程表最终达到上限而无法分配新进程,这种情况是可以忍受的。
输出样例ps -el | grep 'Z'
:
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
5 Z 0 2648 1 0 75 0 - 0 exit ? 00:00:00 sendmail <defunct>
1 Z 51 2656 1 0 75 0 - 0 exit ? 00:00:00 sendmail <defunct>
1 Z 0 2670 1 0 75 0 - 0 exit ? 00:00:02 crond <defunct>
4 Z 0 2874 1 0 82 0 - 0 exit ? 00:00:00 mysqld_safe <defunct>
5 Z 0 28104 1 0 76 0 - 0 exit ? 00:00:00 httpd <defunct>
5 Z 0 28716 1 0 76 0 - 0 exit ? 00:00:06 lfd <defunct>
5 Z 74 10172 1 0 75 0 - 0 exit ? 00:00:00 sshd <defunct>
5 Z 0 11199 1 0 75 0 - 0 exit ? 00:00:00 sendmail <defunct>
5 Z 0 11202 1 0 75 0 - 0 exit ? 00:00:00 sendmail <defunct>
5 Z 0 11205 1 0 75 0 - 0 exit ? 00:00:00 sendmail <defunct>
5 Z 0 11208 1 0 75 0 - 0 exit ? 00:00:00 sendmail <defunct>
5 Z 0 11211 1 0 75 0 - 0 exit ? 00:00:00 sendmail <defunct>
5 Z 0 11240 1 0 75 0 - 0 exit ? 00:00:00 sendmail <defunct>
5 Z 0 11246 1 0 75 0 - 0 exit ? 00:00:00 sendmail <defunct>
5 Z 0 11249 1 0 75 0 - 0 exit ? 00:00:00 sendmail <defunct>
5 Z 0 11252 1 0 75 0 - 0 exit ? 00:00:00 sendmail <defunct>
1 Z 0 14106 1 0 80 0 - 0 exit ? 00:00:00 anacron <defunct>
5 Z 0 14631 1 0 75 0 - 0 exit ? 00:00:00 sendmail <defunct>
这是操作系统错误吗?配置错误?我正在寻找这个问题的根源。谢谢
答案1
如果父进程死亡,则该进程将成为僵尸进程。如果是这样,init 将成为孤儿进程的新父进程。
Init 将定期执行 wait(),并因此收获以 init 为父级的所有进程。这是同步发生的,这意味着它会等待分别收获每个进程。如果进程没有正确收获,这可能会使进程有时更长。
它可能表明系统存在错误,也可能不是。我建议使用内核邮件列表或与内核相关的 dist 特定邮件列表。
答案2
当进程调用“exit”系统调用时,它可能尚未完全完成。例如,它可能有待处理的 IO 操作正在进行中(例如,内核中仍有部分缓冲的大型写入)。发生这种情况时,内核必须先完成所有待处理的操作,然后才能完成退出系统调用。
但是,一旦进程调用“退出”,它就不再处于活动状态,内核将从中回收尽可能多的资源。因此,即使内核尚未准备好回收它,它也将被报告为僵尸进程。
通常情况下,内核可以在几分之一秒内清理进程,退出系统调用完成,父进程得到通知,进程被回收。但是,如果进程被挂起在永远无法完成的 IO 进程上(例如,在 nfs 和限时身份验证的各种组合中很容易发生这种情况),这可能会导致问题。当这种情况发生时,恐怕你唯一的选择就是重新启动。
答案3
僵尸进程无法被 init 收割。父进程有责任通过调用 wait*() 来收割它们。这些进程被留下来,以便父进程可以获取返回值。