执行"kill <PID>"命令并不会真正终止进程,为什么呢?

我正在努力提高我的命令行技能,但遇到了一个问题,无法终止一个进程。我输入kill 2200,其中2200是我的PID,但进程没有被终止。经过几分钟的等待后,它仍然在topps aux中显示。 我甚至尝试使用sudo来输入命令,但没有任何结果。 有什么想法为什么会出现这种情况吗?
编辑 我发现了一个奇怪的依赖关系,即fg会更新进程列表。
x@xxx:/etc/grub.d$ ps
  PID TTY          TIME CMD
 1723 pts/0    00:00:00 bash
 2200 pts/0    00:00:00 top
 2202 pts/0    00:00:00 top
 2258 pts/0    00:00:00 ps
x@xxx:/etc/grub.d$ fg
top

x@xxx:/etc/grub.d$ ps
  PID TTY          TIME CMD
 1723 pts/0    00:00:00 bash
 2200 pts/0    00:00:00 top
 2620 pts/0    00:00:00 ps
x@xxx:/etc/grub.d$ fg
top

x@xxx:/etc/grub.d$ ps
  PID TTY          TIME CMD
 1723 pts/0    00:00:00 bash
 2621 pts/0    00:00:00 ps

那是什么进程?你有没有检查过这个进程是否可能是僵尸进程?如果是的话,你需要终止父进程。 - htorque
这个过程是“顶级”(如编辑中所列)。我只是想尝试将程序放到后台运行,然后再将其恢复。 - Patryk
2如果你使用CTRL-z暂停一个进程,它会阻止大部分信号,直到你使用"fg"或"bg"命令恢复该进程。 - nos
8个回答

进程可以忽略一些信号。如果你发送SIGKILL信号,它将无法忽略它(也无法捕获它以进行清理)。请尝试:
kill -9 {PID}
请阅读手册页面以了解更多信息。
man kill

32请注意,在某些非常特殊的情况下,一个进程可能处于僵尸/失效状态,即使使用SIGKILL信号也无法终止该进程。在这种情况下,您需要找到父进程并终止父进程。 - Lie Ryan
24如果那个过程走错了一步,那就是KILL DASH NINE - scottl
7有时候没有父进程,这种情况下你就完蛋了。唯一的办法是重新启动机器来终止这个进程。 - user606723
你也可以只使用pkill process,其中process是进程的名称而不是进程ID。 - RobinJ
3杀命令的名字对很多用户(包括我在刚开始时)来说仍然具有误导性。人们会认为当你说“杀死X”时,这意味着真的要杀死X而不是做其他事情。我明白这不会改变任何事情,但我希望他们选择一个更详细的名称... - rbaleksandar
7即使 kill -9 不起作用,进程仍然存在,之后应该做什么? - Douglas Gaskell
有没有一个原因,为什么“kill #9”是有效的?(即我可以更好地记住kill -9是有效的,而不是死记硬背) - user391339
@user391339 每个信号都有它的编号(参见:https://en.wikipedia.org/wiki/Signal_(IPC)#POSIX_signals)。这个编号几乎50年前在UNIX系统上是任意设定的。一些信号非常重要,以至于它们在不同的UNIX系统中保持一致。 - Michał Šrajer
甜美而令人敬畏 - Rafiq
关于-9,"man kill" 几乎没有提到任何信息:"可以通过三种方式指定替代信号:-9、-SIGKILL 或 -KILL。" 我不太明白这意味着什么是杀死。是否可以使用 -KILL 替代 -9,例如 kill -KILL {PID} - run_the_race

如果没有给kill命令传递任何参数,它会发送信号编号15(SIGTERM)。进程可以忽略这个信号。这个信号通知进程清理自己的工作并正确地结束自己。这是一个友好的方式。 你也可以发送信号编号9(SIGKILL),这个信号进程无法忽略。进程甚至无法意识到信号的存在,因为是内核结束了进程,而不是进程自己。这是一种恶意的方式。 有人说kill -9 总是有效的,但这是一个错误的认识。在某些情况下,即使使用kill -9命令也无法杀死进程。例如,当一个进程处于D状态(不可中断的睡眠状态)时。每当一个进程等待I/O操作时(通常时间不会很长),它会进入这个状态。所以,如果一个进程等待I/O操作(比如在一个有问题的硬盘上),并且没有正确设置超时机制,那么你就无法杀死这个进程。无论你做什么都没有用。你只能尝试让进程继续访问文件。

5这非常有帮助,我因为网络磁盘的I/O访问挂起而多次遇到过这个问题,一直想知道为什么无法终止冻结的进程。是否有关于这个特定问题以及如何解决它的更多文档资料? - Jonathan H
我遇到了这个问题,使用/usr/bin/kate -b sftp://foo/root/bar.txt命令时无法关闭。即使杀掉了父进程,它仍然被PID 1继承。我甚至尝试使用gdb关闭文件描述符,但由于进程挂起,无法附加。 - Sarke
谢谢!我不得不关闭VSCode,这样文件才能变得可用。 - Mendy

尽管它的名字是“kill”,但实际上它并不会杀死进程,而是向其发送信号。根据man页面的描述: “kill - 向进程发送信号” kill [pid]命令发送的默认信号是SIGTERM,通常但不一定要求进程终止。你完全可以编写一个程序,在收到SIGTERM信号时播放愉快的曲调,但这并不被推荐。 另一个常见的信号是SIGHUP,通常用于要求程序重新读取其配置文件。 如果你真的想要终止一个程序,你需要使用SIGKILL信号,即执行kill -9 [pid]命令。

听起来你可能正在暂停一个进程(可能是通过在终端中按下Ctrl-Z)。在这种状态下,进程将不会响应SIGTERM信号,因为它被冻结了。运行'fg'命令可以解除进程的冻结,使其能够接收信号并自行终止。这可能解释了为什么'fg'命令似乎更新了进程列表。


1那么如何找到连接的终端呢? - ruX

这是我以前用来在端口80上运行本地主机的方法(通过angular cli) 获取在端口80上运行的应用程序信息
sudo lsof -i tcp:80

After That 
sudo kill -9 3348

其中3348是正在运行的进程的pid


从C++中,我执行了以下操作:

kill(4024, SIGKILL);
在Linux(Ubuntu)终端上,
$ ps -ax | grep my_su
输出结果为:
4024 pts/1    Z+     0:00 [my_subscriber] <defunct>
看起来,它(4024)似乎还在存活。然而,一旦我终止了调用上述“kill”语句的父进程,4024就不再出现了。现在我判断“僵尸”进程只是一个显示的行,并决定忽略它。希望我的经验能对某人有所帮助。干杯!

你还可以使用kill -l命令来显示你的架构支持的信号,并了解更多关于你可能希望使用的信号以正确发送信号的信息。 注意:正如其他人可能已经提到的那样,除非是僵尸进程,否则不建议使用kill -9 {PID}命令。一旦进程接收到SIGKILL信号,它将立即关闭而不进行清理或任何其他适当的程序。

如果你试图使用PID杀死一个进程,但它仍然在另一个PID上运行,那么看起来你可能是在不同的账户下启动了该进程,很可能是root账户。所以请使用sudo su登录并将其杀掉。