杀死僵尸进程的另一种方法

杀死僵尸进程的另一种方法

我刚刚注意到 CentOS 6.8(Final) 上有一些僵尸进程,试图杀死它们,但它们仍然存在:

[root@host user]# ps -ef | grep git
tomcat     746     1  0 Jul18 ?        00:00:00 git clone https://github.com/angular/bower-angular.git -b v1.3.20 --progress . --depth 1
tomcat     747   746  0 Jul18 ?        00:00:00 [git-remote-http] <defunct>
root     20776 20669  0 09:03 pts/3    00:00:00 grep git
tomcat   29970     1  0 Jul18 ?        00:00:00 git clone https://github.com/components/jqueryui.git -b 1.12.0 --progress . --depth 1
tomcat   29971 29970  0 Jul18 ?        00:00:00 [git-remote-http] <defunct>

[root@host user]# kill 746 747 29970 29971

[root@host user]# ps -ef | grep git
tomcat     746     1  0 Jul18 ?        00:00:00 git clone https://github.com/angular/bower-angular.git -b v1.3.20 --progress . --depth 1
tomcat     747   746  0 Jul18 ?        00:00:00 [git-remote-http] <defunct>
root     21525 20669  0 09:26 pts/3    00:00:00 grep git
tomcat   29970     1  0 Jul18 ?        00:00:00 git clone https://github.com/components/jqueryui.git -b 1.12.0 --progress . --depth 1
tomcat   29971 29970  0 Jul18 ?        00:00:00 [git-remote-http] <defunct>

正如你所看到的,它们已经运行了两个月,如果它们没有害处,我也会摆脱它们,有什么其他方法可以杀死僵尸吗?

答案1

你无法杀死僵尸(进程),它已经死了。它只是等待其父进程执行wait(2)并收集其退出状态。除了进程表条目之外,它不会占用系统上的任何资源。

您可以发送SIGCHLD给其父级,让其知道其子级之一已终止(即请求其收集子级的退出状态)。该信号可以被忽略(这是默认的):

kill -CHLD <PPID>

(替换<PPID>为父级的实际PID。)

或者您可以杀死父进程,以便init(PID 1)继承僵尸进程并正确获取它(init继承任何孤儿进程并wait(2)定期执行是其主要任务之一)。但不建议杀死父母。一般来说,僵尸进程的创建表明存在编程问题,您应该尝试修复或报告该问题。

答案2

正如 Heemayl 所说,你实际上无法杀死僵尸。它已经死了……

但是,您面临的问题看起来像是命令的问题git clone。它不知何故被卡住了。可能会超时或以其他方式失败?通常,由于某些 I/O,进程会陷入SIGTERM无法工作的地步SIGINT

在这种情况下,要杀死它,您需要使用-9命令行选项。这意味着发送SIGKILL信号。其实你-KILL也可以用。

[root@host user]# kill -KILL 746 29970

要获取可用信号的列表,请使用 list 命令行选项。

[root@host user]# kill -l

这会向您显示数字和名称(您会看到 #9 表示 SIGKILL。)

答案3

寻找僵尸进程:

ps aux | grep -w Z | grep -v grep

ps -eo stat,ppid | grep -w Z

要杀死僵尸进程,需要杀死父 ID,即 PPID:

kill PPID1 PPID2

kill $(ps -eo stat,ppid|grep -w Z|awk '{print $2}'|tr "\n" " ")

答案4

当父进程死亡时,所有僵尸进程都会被清理。不要仅仅为了清理僵尸进程而终止父进程。当您重新运行程序时,它会再次出现。通过正确调用“wait()”或“waitpid()”系统调用来修复您的程序。

相关内容