我刚刚注意到 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()”系统调用来修复您的程序。