我的 NAS 上的传输间歇性挂起。如果我发送 SIGTERM,它不会从进程列表中消失,并且<defunct>
旁边会出现一个标签。如果我发送 SIGKILL,它仍然不会消失,并且我无法终止父级,因为父级是init
.我摆脱该进程并重新启动 Transmission 的唯一方法是重新启动。
我意识到我能做的最好的事情就是尝试修复传输(我已经尝试过),但我是编译新手,我想确保我的 torrent 在我开始乱搞之前完成。
答案1
您无法杀死<defunct>
进程(也称为僵尸进程),因为它已经死亡。系统保留僵尸进程供父进程收集退出状态。如果父进程不收集退出状态,那么僵尸进程将永远保留。摆脱这些僵尸进程的唯一方法是杀死父进程。如果父进程处于 init 状态,则只能重新启动。
僵尸进程几乎不占用任何资源,因此让它们徘徊不会产生性能成本。尽管存在僵尸进程通常意味着您的某些程序存在错误。 Init 通常应该收集所有子进程。如果 init 有僵尸子进程,那么 init 中就有一个错误(或者是其他原因,但它本身就是一个错误)。
答案2
任何试图修复 Transmission 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);
答案3
今天我发现一个已失效的进程,由 init 拥有,并且大量占用系统资源。显然某处存在错误,但我想让未来的访问者知道这是可能的,他们应该查看僵尸的线程以获取更多信息。看https://stackoverflow.com/questions/22234609/defunct-processes-using-cpu/67840842#67840842