如果“kill -9”不起作用怎么办?

tsh*_*ang 556 process kill

我有一个无法杀死的进程kill -9 <pid>。在这种情况下有什么问题,特别是因为我是该流程的所有者。我认为没有什么可以逃避这个kill选择。

Gil*_*il' 654

kill -9( SIGKILL ) 始终有效,前提是您有权终止该进程。基本上,该进程必须由您启动,而不是 setuid 或 setgid,或者您必须是 root。有一个例外:即使是 root 也不能​​向 PID 1(init进程)发送致命信号。

但是kill -9不能保证立即工作。所有信号,包括 SIGKILL,都是异步传递的:内核可能需要一些时间来传递它们。通常,传递一个信号最多需要几微秒,只是目标获得时间片所需的时间。但是,如果目标已经阻塞了信号,则信号将排队等待,直到目标解除阻塞为止。

通常,进程不能阻塞 SIGKILL。但是内核代码可以,并且进程在调用系统调用时会执行内核代码。内核代码在中断系统调用时会阻塞所有信号,这将导致内核中某处的数据结构格式错误,或者更常见的是违反某些内核不变量。因此,如果(由于错误或错误设计)系统调用无限期阻塞,则可能实际上无法终止该进程。(但是如果进程完成了系统调用,它就会被终止。)

被系统调用阻塞的进程处于不间断睡眠状态。该pstop命令(在大多数Unix系统)显示它的状态D(原本为“ d ISK”,我认为)。

长时间不间断睡眠的典型案例是当服务器没有响应时进程通过NFS访问文件;现代实现往往不会强加不可中断的睡眠(例如,在 Linux 下,intr挂载选项允许信号中断 NFS 文件访问)。

如果进程长时间处于不间断睡眠状态,您可以通过将调试器附加到它,运行诊断工具,如stracedtrace(或类似工具,取决于您的 unix 风格)来获取有关它正在做什么的信息,或者与其他诊断机制,如在 Linux 下。有关如何在不间断睡眠中调查进程的更多讨论,请参阅Can't kill wget process with `kill -9`/proc/PID/syscall

您有时可能会在或输出中看到标记的条目Z(或H在 Linux 下,我不知道有什么区别)。这些在技术上不是进程,它们是僵尸进程,它们只不过是进程表中的一个条目,保留在周围以便父进程可以在其子进程死亡时得到通知。当父进程注意到(或死亡)时,它们会消失。pstop

  • 您的回复看起来自相矛盾。你开始告诉 SIGKILL 总是有效,但最后引用了不间断睡眠的情况,在这种情况下,SIGKILL 在关闭内核之外可能永远不会工作。还有两种情况 SIGKILL 不起作用。显然,对于僵尸,因为您无法杀死已经死掉的进程,而对于 init,这在设计上会忽略 SIGKILL 信号。 (110认同)
  • @jlliagre:杀死僵尸没有意义,它一开始就没有生命。在可中断睡眠中杀死进程*确实*有效,它只是(与其他信号一样)异步。我试图在我的编辑中澄清这一点。 (46认同)
  • `man 5 nfs`:“内核 2.6.25 后不推荐使用 `intr`/`nointr` 挂载选项。只有 SIGKILL 可以中断这些内核上挂起的 NFS 操作,如果指定,则忽略此挂载选项以提供向​​后兼容性使用较旧的内核。” (13认同)
  • @imz--IvanZakharyaschev 我不知道(但我可能不知道)。使用 sshfs,作为最后的手段,您可以终止 `sshfs` 进程(对于任何其他 FUSE 文件系统也是如此:您总是可以通过这种方式强制卸载)。 (6认同)
  • 我也写了杀死僵尸没有意义,但这并不能阻止很多人尝试并抱怨。在可中断睡眠中杀死进程确实是设计使然,但我说的是在不可中断睡眠中杀死进程,如果系统调用永远不会唤醒它可能会失败。 (4认同)
  • 当远程服务器无法访问时,我在杀死访问 `sshfs` 挂载的 `ls` 进程时遇到问题。是否有 FUSE 或 sshfs 的挂载选项,我将来可以使用它来避免这种情况?2.6.30 内核 (2认同)
  • @imz--IvanZakharyaschev:呵呵,微内核的用户早就知道这种便利了。磁盘完全卡住了?杀死并重生磁盘服务器。NFS卡住了?杀死并重生 nfs 守护进程。由于一切都是一个进程,因此真正挂起一个微内核操作系统是非常困难的。 (2认同)
  • @jww 有些进程状态无法杀死进程,但信号已排队且无法取消。正如我所解释的,SIGKILL 总是“有效”,但它并不总是“立即”有效。 (2认同)
  • @GreenRaccoon23 有效的不是多次发送信号,发送一次就会产生完全相同的效果。有效的方法是等待足够长的时间来处理信号。 (2认同)
  • @sudo 重新启动不会增加搞砸事情的可能性。这在数学上并不是不可能的,但重新启动不会是造成混乱的原因。如果有效的不可杀死进程的原因是有错误的驱动程序或硬件,那么有错误的驱动程序或硬件可能会导致混乱,但重新启动不会使情况变得更糟。 (2认同)

Mac*_*tka 113

有时进程存在且无法被杀死,原因如下:

  • 成为僵尸。即父进程没有读取退出状态。这样的过程除了PID条目外不消耗任何资源。在top它发出信号 Z
  • 错误的不间断睡眠。它不应该发生,但有时会发生错误的内核代码和/或错误的硬件。唯一的方法是重新启动或等待。在top它是由信号D.

  • @xenoterracide:最终是的,但是如果父进程仍然存在(例如它是 gnome-session 或完成类似角色的东西),你仍然可能有僵尸。从技术上讲,清理是父母的工作,但如果僵尸是孤儿,init 会在它之后清理(术语是 unix 类是闭门完成的原因 - 任何人在一句话中听到孤儿、僵尸和杀戮都可能有错误的印象)。 (20认同)
  • “……唯一的办法就是重启或者等待。” 等待多久?五个月过去了,我的僵尸还在那里。 (8认同)
  • @Luc M:AFAIK 否(至少在 Linux 上)-进程表中的条目除外(即 PID 以及所有者、退出状态等信息)。它只是等待来自它终止的部分的确认的进程。 (7认同)
  • 僵尸不消耗资源? (3认同)
  • @DarenW 直到父母承认孩子的死亡。详情请咨询程序作者。 (3认同)

Jos*_*osh 35

听起来您可能有一个僵尸进程。这是无害的:僵尸进程消耗的唯一资源是进程表中的一个条目。当父进程死亡或对其子进程的死亡做出反应时,它将消失。

您可以使用top或 以下命令查看进程是否为僵尸进程:

ps aux | awk '$8=="Z" {print $2}'
Run Code Online (Sandbox Code Playgroud)

  • 嗯,我总是不喜欢这种带有 `ps` 的“硬”字段名称。谁能确定必填字段*总是*是第 8 个,并且在所有 Unices 中都实现了 `ps`? (17认同)

Law*_*ceC 26

检查您的/var/log/kern.log/var/log/dmesg(或等价物)是否有任何线索。根据我的经验,只有在 NFS 挂载的网络连接突然断开或设备驱动程序崩溃时才会发生这种情况。我相信,如果硬盘驱动器崩溃也可能发生。

您可以使用lsof查看进程打开了哪些设备文件。

  • +1 提及 NFS。几年前,这种情况每隔几个月就会发生在我身上——如果 NFS 服务器崩溃,所有(打过补丁的)RHEL 机器上的 NFS 客户端都会挂起。`kill -9` 通常不起作用,即使等待了 60 分钟。唯一的解决办法是重新启动。 (6认同)

xen*_*ide 17

如果@Maciej@Gilles的答案不能解决您的问题,并且您不认识这个过程(并且询问您的发行版是什么并没有找到答案)。检查 Rootkit 和任何其他表明您已被拥有的迹象。Rootkit 能够阻止您终止进程。事实上,许多都能够阻止你看到它们。但是如果他们忘记修改 1 个小程序,他们可能会被发现(例如,他们修改了top,但没有修改htop)。很可能情况并非如此,但安全总比抱歉好。


lep*_*epe 15

首先,检查它是否是一个僵尸进程(这很有可能):

ps -Al
Run Code Online (Sandbox Code Playgroud)

你会看到类似的东西:

0 Z  1000 24589     1  0  80   0 -     0 exit   ?        00:00:00 soffice.bin <defunct>
Run Code Online (Sandbox Code Playgroud)

(注意左边的“Z”)

如果第 5 列不是 1,则表示它有一个父进程。 尝试杀死该父进程 id

如果它的 PPID = 1,不要杀死它!!,想想还有哪些其他设备或进程可能与之相关。

例如,如果您使用的是已挂载的设备或 samba,请尝试卸载它。那可能会释放Zombie进程。

注意:如果ps -Al(或top)显示“D”而不是“Z”,则可能与远程安装(如 NFS)有关。根据我的经验,重新启动是唯一的方法,但您可以查看更详细地涵盖该情况的其他答案。


Dev*_*ris 13

杀死实际上意味着发送信号。您可以发送多种信号。kill -9 是一个特殊信号。

当发送信号时,应用程序会处理它。如果不是内核处理它。所以你可以在你的应用程序中捕获一个信号。

但我说 kill -9 很特别。它的特殊之处在于应用程序没有得到它。它直接进入内核,然后在第一个可能的机会真正杀死应用程序。换句话说,它死了

kill -15 发送信号 SIGTERM,它代表 SIGNAL TERMINATE,换句话说就是告诉应用程序退出。这是告诉应用程序该关闭的友好方式。但如果应用程序没有响应,kill -9 将杀死它。

如果 kill -9 不起作用,则可能意味着您的内核不正常。重新启动是为了。我不记得曾经发生过。

  • 15 是 SIGTERM(友好击杀),而不是 SIGHUP。SIGHUP 用于控制终端关闭或通信通道丢失 (5认同)

jll*_*gre 10

init 进程不受 SIGKILL 的影响。

这也适用于内核线程,即 PPID 等于 0 的“进程”。


小智 10

正如其他人所提到的,无法立即终止处于不间断睡眠状态的进程(或者,在某些情况下,根本无法终止)。值得注意的是,增加了另一个进程状态 TASK_KILLABLE 是为了解决某些场景下的这个问题,特别是进程等待 NFS 的常见情况。见http://lwn.net/Articles/288056/

不幸的是,我不相信这会在内核中的任何地方使用,但 NFS 除外。


小智 6

做了一个小脚本,对我帮助很大!

您可以使用它来杀死路径中具有给定名称的任何进程(注意这一点!!)或者您可以使用“-u username”参数杀死给定用户的任何进程。

#!/bin/bash

if [ "$1" == "-u" ] ; then\n
        PID=`grep "$2" /etc/passwd | cut -d ":" -f3`
        processes=`ps aux | grep "$PID" | egrep -v "PID|ps \-au|killbyname|grep" | awk '{ print $2}'`
        echo "############# Killing all processes of user: $2 ############################"
else
        echo "############# Killing processes by name: $1 ############################"
        processes=`ps aux | grep "$1" | egrep -v "killbyname|grep" | awk '{ print $2}' `
fi


for process in $processes ; do
        # "command" stores the entire commandline of the process that will be killed
        #it may be useful to show it but in some cases it is counter-productive
        #command=`ps aux | grep $process | egrep -v "grep" | awk '{ print $2 }'`
        echo "Killing process: $process"
        echo ""
        kill -9 $process
done
Run Code Online (Sandbox Code Playgroud)

  • 您可以在此处发布代码,而不仅仅是链接到它。 (4认同)
  • 用(或至少代替)代码添加一些描述...... (3认同)

dag*_*729 5

在某些情况下,即使您向进程发送 kill -9,该 pid 也会停止,但该进程会自动重新启动(例如,如果您尝试使用gnome-panel,它将重新启动):这里可能是这种情况吗?

  • 当发生这样的事情时,PID 实际上会发生变化。所以我会注意到。 (8认同)

小智 5

最初从这里开始:

检查 strace 是否显示任何内容

strace -p <PID>
Run Code Online (Sandbox Code Playgroud)

尝试使用 gdb 附加到进程

gdb <path to binary> <PID>
Run Code Online (Sandbox Code Playgroud)

如果该进程正在与您可以卸载的设备进行交互,删除其内核模块,或物理断开/拔出...然后尝试。


Chr*_*uet 5

我有这样的问题。这是一个我用+启动strace并中断的程序。它最终处于(跟踪或停止)状态。我不知道它到底是怎么发生的,但它是无法用 杀死的。CtrlCTSIGKILL

长话短说,我成功地杀死了它gdb

gdb -p <PID>
> kill
Kill the program being debugged? (y or n) y
> quit
Run Code Online (Sandbox Code Playgroud)