it-swarm.cn

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

我有一个无法使用kill -9 <pid>杀死的进程。在这种情况下有什么问题,尤其是因为我是该过程的所有者。我认为kill选项无可避免。

491
tshepang

kill -9[〜#〜] sigkill [〜#〜] )始终有效,只要您有权终止该进程即可。基本上,该过程必须由您启动而不是setuid或setgid,或者您必须是root用户。有一个例外:即使root也无法向PID 1发送致命信号(init进程)。

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

通常,进程无法阻止SIGKILL。但是内核代码可以并且进程在调用 系统调用 时执行内核代码。当中断系统调用时,内核代码会阻塞所有信号,从而导致内核中某个地方的数据结构格式错误,或更常见的是会破坏某些内核不变式。因此,如果(由于错误或错误设计)系统调用无限期地阻塞,则可能实际上没有办法终止该过程。 (但是,如果will进程完成了系统调用,它将被杀死。)

系统调用中阻塞的进程处于 不间断睡眠pstop命令将在大多数情况下将其显示为D状态(最初是“disk”,我认为)。

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

有时您会在ZH输出中看到标记为ps的条目(或在Linux下为top,我不知道区别是什么)。从技术上讲,这些进程不是僵尸进程,它们只是进程表中的一个条目而已,它们始终保持存在,以便可以将其子进程的死亡通知父进程。当父进程 引起注意 (或死亡)时,它们将消失。

577

有时存在进程,由于以下原因无法将其杀死:

  • 僵尸。即处理哪个父级没有读取退出状态。除了PID输入之外,该过程不会消耗任何资源。在top中信号为Z
  • 错误的不间断睡眠。它应该不会发生,但有时会结合错误的内核代码和/或错误的硬件。唯一的方法是重新启动或等待。在top中由D发出信号。
101
Maciej Piechotka

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

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

ps aux | awk '$8=="Z" {print $2}'
32
Josh

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

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

26
LawrenceC

如果@ Maciej 和@ Gilles 的答案不能解决您的问题,并且您不了解该过程(并且询问发行版的内容,不要提出答案)。检查Rootkit以及您拥有的其他任何符号。 Rootkit能够阻止您终止进程。实际上,许多功能都可以阻止您看到它们。但是,如果他们忘记修改1个小程序,则可能会发现它们(例如,他们修改了top,但没有修改htop)。很有可能不是这种情况,但是比后悔更安全。

17
xenoterracide

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

发送信号时,应用程序将对其进行处理。如果不是,内核会处理它。因此您可以在应用程序中捕获信号。

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

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

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

11
DeveloperChris

首先,检查其是否为僵尸进程(这很有可能):

ps -Al

您将看到类似以下内容:

0 Z  1000 24589     1  0  80   0 -     0 exit   ?        00:00:00 soffice.bin <defunct>

(请注意左侧的“ Z”)

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

如果其PPID = 1,则不要杀了它!,请考虑可能与之相关的其他设备或进程。

例如,如果您使用的是已安装的设备或samba,请尝试将其卸载。那可能会释放僵尸进程。

[〜#〜] note [〜#〜]:如果ps -Al(或top)显示的是“ D”而不是“ Z”,它可能与远程安装(如NFS)有关。以我的经验,重新启动是到达那里的唯一方法,但是您可以检查涵盖该情况的其他答案。

11
lepe

初始化过程不受SIGKILL的影响。

对于内核线程,即PPID等于0的“进程”也是如此。

10
jlliagre

正如其他人所提到的,不间断睡眠的过程无法立即被杀死(或在某些情况下根本无法杀死)。值得注意的是,在某些情况下,尤其是在进程正在等待NFS的常见情况下,添加了另一个进程状态TASK_KILLABLE来解决此问题。参见 http://lwn.net/Articles/288056/

不幸的是,我不相信这会在NFS之外的内核中使用。

10
user36054

制作了一个小脚本,对我有很大帮助!

您可以使用它杀死路径中具有给定名称的任何进程(请注意!!),也可以使用“ -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
6
user36035

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

5
dag729

来自 原为此处

检查strace是否显示任何内容

strace -p <PID>

尝试使用gdb附加到进程

gdb <path to binary> <PID>

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

2
nmz787

我有点这个问题。这是我用strace启动并用Ctrl + C中断的程序。它最终以T(已跟踪或已停止)状态。我不知道它是怎么发生的,但是用SIGKILL不能杀死它。

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

gdb -p <PID>
> kill
Kill the program being debugged? (y or n) y
> quit
1

根据吉勒斯回答的线索,我有一个进程标记为“ Z”(以ps为单位的“”),该进程正在使用系统资源,它甚至有一个正在监听的端口,您可以连接它。这是在对其执行kill -9之后。它的父代为“ 1”(即init),因此从理论上讲它应该消失。但这不是,尽管没有运行,但它仍然存在。

因此,就我而言,这是僵尸,但仍在消耗资源... FWIW。

并且无法被kill -9杀死。

它的父级是init,但没有被收割(清理)。即init生了一个僵尸孩子。

重新启动不是解决该问题所必需的。尽管重启将“解决问题” /使其更快地关机。只是不优雅,这仍然是可能的。

这是僵尸进程拥有的LISTEN端口(还有一些其他端口,例如CLOSE_WAIT status将localhost连接到localhost)。而且它甚至仍然接受连接。即使是僵尸。我想它还没有清理端口,因此尽管没有被接受的机会,传入的连接仍被添加到tcp侦听端口的待办事项中。

事实证明,我内部有一个线程正在执行“系统调用”(在本例中为ioctl),这需要花费几个小时才能返回(这是预期的)。显然,系统无法“从头到尾”杀死它,直到它从那儿返回为止。几个小时后,它清理干净,所有插座均按预期自动关闭,依此类推。那是一段令人沮丧的死亡时间!

另外,请检查dmesg以查看是否存在内核崩溃(即内核错误)。

0
rogerdpack