如何杀死父进程为 init 的 <defunct> 进程?

And*_*y E 27 kill signals process-management init zombie-process

传输间歇性地挂在我的 NAS 上。如果我发送 SIGTERM,它不会从进程列表中消失,并且<defunct>旁边会出现一个标签。如果我发送 SIGKILL,它仍然不会消失并且我无法终止父级,因为父级是init. 我可以摆脱该过程并重新启动传输的唯一方法是重新启动。

我意识到我能做的最好的事情就是尝试修复传输(我已经尝试过),但我是编译的新手,我想确保在我开始搞乱它之前我的种子已经完成。

les*_*ana 35

你不能杀死一个<defunct>进程(也称为僵尸进程),因为它已经死了。系统为父进程保留僵尸进程以收集退出状态。如果父进程不收集退出状态,则僵尸进程将永远存在。摆脱这些僵尸进程的唯一方法是杀死父进程。如果父级是 init,那么您只能重新启动。

僵尸进程几乎不占用资源,因此让它们徘徊不会产生性能成本。尽管有僵尸进程通常意味着您的某些程序中存在错误。Init 通常应该收集所有的孩子。如果 init 有僵尸子进程,那么 init 中就有一个错误(或者其他地方,但它是一个错误)。

http://en.wikipedia.org/wiki/Zombie_process

  • @D.Shawley:不过,`init` 可能有错误。init 替换 `runit` 有一个导致此问题的错误。 (15认同)
  • `init` 永远不能有僵尸孩子。来自维基百科文章:_当一个进程失去其父进程时,init 成为它的新父进程。Init 周期性地执行 wait 系统调用以收割任何以 init 为父节点的僵尸。_ `init` 的职责之一是收割孤儿和无父僵尸。 (9认同)
  • init 可以有不复存在的孩子,也许是由于错误,但它可以。因为我现在正在看一个。 (2认同)

小智 6

任何试图修复传输 C 源代码的人都应该阅读“双叉”技巧以避免僵尸和信号处理程序......以及如何将其用作智能可变参数生成函数的一部分(请参阅在 Unix 中生成)。

excerpt from: 
   "Spawning in Unix", http://lubutu.com/code/spawning-in-unix

Double fork
This trick lets you spawn processes whilst avoiding zombies, without 
installing any signal handler. The first process forks and waits for its 
child; the second process forks and immediately exits and is reaped;
the third process is adopted by init, and executes the desired program. 
All zombies accounted for, since init is always waiting.

if(fork() == 0) {
   if(fork() == 0) {
       execvp(file, argv);
       exit(EXIT_FAILURE);
   }
   exit(EXIT_SUCCESS);
}
wait(NULL);
Run Code Online (Sandbox Code Playgroud)