我有一个无法杀死的进程kill -9 <pid>。在这种情况下有什么问题,特别是因为我是该流程的所有者。我认为没有什么可以逃避这个kill选择。
Gil*_*il' 654
kill -9( SIGKILL ) 始终有效,前提是您有权终止该进程。基本上,该进程必须由您启动,而不是 setuid 或 setgid,或者您必须是 root。有一个例外:即使是 root 也不能向 PID 1(init进程)发送致命信号。
但是kill -9不能保证立即工作。所有信号,包括 SIGKILL,都是异步传递的:内核可能需要一些时间来传递它们。通常,传递一个信号最多需要几微秒,只是目标获得时间片所需的时间。但是,如果目标已经阻塞了信号,则信号将排队等待,直到目标解除阻塞为止。
通常,进程不能阻塞 SIGKILL。但是内核代码可以,并且进程在调用系统调用时会执行内核代码。内核代码在中断系统调用时会阻塞所有信号,这将导致内核中某处的数据结构格式错误,或者更常见的是违反某些内核不变量。因此,如果(由于错误或错误设计)系统调用无限期阻塞,则可能实际上无法终止该进程。(但是如果进程完成了系统调用,它就会被终止。)
被系统调用阻塞的进程处于不间断睡眠状态。该ps或top命令(在大多数Unix系统)显示它的状态D(原本为“ d ISK”,我认为)。
长时间不间断睡眠的典型案例是当服务器没有响应时进程通过NFS访问文件;现代实现往往不会强加不可中断的睡眠(例如,在 Linux 下,intr挂载选项允许信号中断 NFS 文件访问)。
如果进程长时间处于不间断睡眠状态,您可以通过将调试器附加到它,运行诊断工具,如strace或dtrace(或类似工具,取决于您的 unix 风格)来获取有关它正在做什么的信息,或者与其他诊断机制,如在 Linux 下。有关如何在不间断睡眠中调查进程的更多讨论,请参阅Can't kill wget process with `kill -9`。/proc/PID/syscall
您有时可能会在或输出中看到标记的条目Z(或H在 Linux 下,我不知道有什么区别)。这些在技术上不是进程,它们是僵尸进程,它们只不过是进程表中的一个条目,保留在周围以便父进程可以在其子进程死亡时得到通知。当父进程注意到(或死亡)时,它们会消失。pstop
Mac*_*tka 113
有时进程存在且无法被杀死,原因如下:
top它发出信号 Ztop它是由信号D.Jos*_*osh 35
听起来您可能有一个僵尸进程。这是无害的:僵尸进程消耗的唯一资源是进程表中的一个条目。当父进程死亡或对其子进程的死亡做出反应时,它将消失。
您可以使用top或 以下命令查看进程是否为僵尸进程:
ps aux | awk '$8=="Z" {print $2}'
Run Code Online (Sandbox Code Playgroud)
Law*_*ceC 26
检查您的/var/log/kern.log和/var/log/dmesg(或等价物)是否有任何线索。根据我的经验,只有在 NFS 挂载的网络连接突然断开或设备驱动程序崩溃时才会发生这种情况。我相信,如果硬盘驱动器崩溃也可能发生。
您可以使用lsof查看进程打开了哪些设备文件。
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 不起作用,则可能意味着您的内核不正常。重新启动是为了。我不记得曾经发生过。
小智 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)
在某些情况下,即使您向进程发送 kill -9,该 pid 也会停止,但该进程会自动重新启动(例如,如果您尝试使用gnome-panel,它将重新启动):这里可能是这种情况吗?
小智 5
最初从这里开始:
检查 strace 是否显示任何内容
strace -p <PID>
Run Code Online (Sandbox Code Playgroud)
尝试使用 gdb 附加到进程
gdb <path to binary> <PID>
Run Code Online (Sandbox Code Playgroud)
如果该进程正在与您可以卸载的设备进行交互,删除其内核模块,或物理断开/拔出...然后尝试。
我有这样的问题。这是一个我用+启动strace并中断的程序。它最终处于(跟踪或停止)状态。我不知道它到底是怎么发生的,但它是无法用 杀死的。CtrlCTSIGKILL
长话短说,我成功地杀死了它gdb:
gdb -p <PID>
> kill
Kill the program being debugged? (y or n) y
> quit
Run Code Online (Sandbox Code Playgroud)