我有一个无法杀死的进程kill -9 <pid>
。在这种情况下有什么问题,特别是因为我是该流程的所有者。我认为没有什么可以逃避这个kill
选择。
答案1
kill -9
(信号杀死) 总是有效,只要您有权终止该进程。基本上,该进程必须由您启动且不是 setuid 或 setgid,或者您必须是 root。有一个例外:即使 root 也无法向 PID 1(进程init
)发送致命信号。
但kill -9
不保证有效立即地。所有信号(包括 SIGKILL)都是异步传递的:内核可能需要一些时间来传递它们。通常,传递信号最多需要几微秒,正好是目标获得时间片所需的时间。然而,如果目标有屏蔽了信号,信号将排队直到目标解锁它。
通常,进程不能阻止 SIGKILL。但是内核代码可以,并且进程在调用时执行内核代码系统调用。当中断系统调用时,内核代码会阻止所有信号,这会导致内核中某处的数据结构格式错误,或者更常见的是违反某些内核不变量。因此,如果(由于错误或设计错误)系统调用无限期地阻塞,则实际上可能无法终止该进程。 (但是过程将要如果它完成了系统调用,就会被杀死。)
系统调用中阻塞的进程位于不间断的睡眠。ps
or命令top
将(在大多数 unice 上)以状态显示它D
(最初用于“d我想)。
长时间不间断睡眠的一个典型案例是进程访问文件网络文件系统当服务器没有响应时;现代实现往往不会强加不间断睡眠(例如,在 Linux 下,自内核 2.6.25 起,SIGKILL 会中断 NFS 访问上阻塞的进程)。
如果进程长时间处于不间断睡眠状态,您可以通过向其附加调试器、运行诊断工具(例如斯特雷斯或者跟踪(或类似的工具,具体取决于您的 UNIX 风格),或使用其他诊断机制,例如/proc/PID/syscall
在Linux下。看无法使用“kill -9”杀死 wget 进程有关如何研究不间断睡眠中的进程的更多讨论。
有时你可能会在或输出中看到标记的条目Z
(或H
在 Linux 下,我不知道区别是什么)。从技术上讲,它们不是进程,它们是僵尸进程,它们只不过是进程表中的一个条目,保留下来以便父进程可以收到其子进程的死亡通知。当父进程运行时它们就会消失ps
top
关注(或死亡)。
答案2
有时进程存在且无法被终止,原因是:
- 成为僵尸。即父进程没有读取退出状态。这样的进程除了PID条目外不消耗任何资源。其中
top
标有Z - 错误的不间断睡眠。这种情况不应该发生,但由于有缺陷的内核代码和/或有缺陷的硬件的组合,有时会发生这种情况。唯一的方法是重新启动或等待。其中
top
由 D 发出信号。
答案3
听起来你可能有一个僵尸进程。这是无害的:僵尸进程消耗的唯一资源是进程表中的条目。当父进程死亡或对其子进程的死亡做出反应时,它就会消失。
您可以使用top
以下命令查看该进程是否为僵尸进程:
ps aux | awk '$8=="Z" {print $2}'