什么是<defunct>进程,为什么它不被杀死?


180

chrome浏览器没有响应,因此我试图杀死它,但<defunct>并没有消失,进程没有错,并且没有被杀死:

在此处输入图片说明

什么是<defunct>流程,为什么不被杀死?


3
接受的答案提到“ kill -9 PID不起作用”。这是部分正确的:实际上,没有杀戮将起作用。此外,-9应该用作最后的选择。默认情况下,父进程的默认杀死将有99%的时间杀死它并获得所有子进程。“默认终止”是SIGTERM(-15)。我鼓励-9(SIGKILL)的粉丝阅读stackoverflow.com/questions/690415/...
麦克小号

Answers:


172

从您的输出中,我们看到“已终止”,这意味着该进程已完成其任务或已损坏或被杀死,但其子进程仍在运行,或者这些父进程正在监视其子进程。要终止这种过程,终止-9 PID无效。您可以尝试使用此命令杀死它们,但是它将一次又一次地显示出来。

确定哪个是该已终止进程的父进程,然后将其终止。要知道这一点,请运行命令:

ps -ef | grep defunct

UID          PID     PPID       C    STIME      TTY          TIME              CMD
1000       637      27872      0   Oct12      ?        00:00:04 [chrome] <defunct>
1000      1808      1777       0    Oct04     ?        00:00:00 [zeitgeist-datah] <defunct>

然后kill -9 637 27872,确认已终止的进程已经过去ps -ef | grep defunct


13
您无法终止“已终止”的过程。您只能通过杀死其父级来加快在进程表中其条目的删除。
jfs 2014年

57
如果ppid是1init)怎么办?假设我只需要等待?
卢克

7
要自动执行终止操作,您也可以执行此操作(可能需要更改要从输出中剪切的字节):ps -ef | grep defunct | grep -v grep | cut -b8-20 | xargs kill -9
沃伦(Warren

3
@warren谢谢。您也可以通过不执行第二次grep来使其变得更短并且(imo)更简单。只需将第一个grep更改为grep [d]efunct或类似值,它就不会匹配自己。
Thor84no

4
@warren,即使使用SIGKILL,也无法终止已失效的进程。此外,您几乎没有区别地使用kill -9。参见stackoverflow.com/questions/690415/…。如果你想杀死倒闭的孩子,你可以尝试:parents_of_dead_kids=$(ps -ef | grep [d]efunct | awk '{print $3}' | sort | uniq | egrep -v '^1$'); echo "$parents_of_dead_kids" | xargs killkill -9如果需要,请在30秒左右后重新运行脚本。(请注意,我明确禁止杀死Init
Mike S'S

60

手册页ps(1)说

被标记<defunct>的进程是死进程(所谓的“僵尸”),因为它们的父进程未正确销毁它们而得以保留。init(8)如果父进程退出,这些进程将被破坏。

您无法杀死它,因为它已经死了。剩下的唯一内容是过程表中的条目

在Unix和类似Unix的计算机操作系统上,僵尸进程或已淘汰的进程是已完成执行但仍在进程表中具有条目的进程。仍需要此条目,以允许父进程读取其子进程的退出状态。

除非有很多这样的过程,否则这样做没有任何危害。僵尸最终被其父(通过调用wait(2))收割。如果原始父级尚未在其自身的退出之前获得它,则init进程(pid == 1)会在以后的某个时间进行。僵尸进程就是:

一个已经终止的进程,当其退出状态已报告给另一个正在等待终止的进程时,将其删除。


1

谢谢MikeS。我们采取了行动,并编写了一个脚本,该脚本将杀死其父目录为in.telnetd的已失效进程。我们不希望它杀死任何父进程,只是希望知道导致问题的telnetd,如果需要,我们将运行它多次以杀死多个进程。

# egrep -v '^1$ = Make sure the process is not the init process.
# awk '{print $3}' = Print the parent process.

first_parent_of_first_dead_kid=$(ps -ef | grep [d]efunct | awk '{print $3}' | head -n1 | egrep -v '^1$')
echo "$first_parent_of_first_dead_kid"

# If the first parent of the first dead kid is in.telnetd, then kill it.
if ps -ef | grep $first_parent_of_first_dead_kid | grep in.telnetd;then
        echo "We have a defunct process whose parent process is in.telnetd" | logger -t KILL-DEFUNCT-TELNET
        echo "killing $first_parent_of_first_dead_kid" | logger -t KILL-DEFUNCT-TELNET
        kill $first_parent_of_first_dead_kid 2>&1 | logger -t KILL-DEFUNCT-TELNET
fi

1

扩大帕丁顿的答案。

从您的输出中,我们看到一个defunct,这意味着此进程已完成其任务,或者已被破坏或杀死。它的父进程仍在运行,并且没有注意到它死掉的孩子。

kill -9 PID 将无法工作(已死)。

要确定此子进程的父级,请运行以下命令:

ps -ef | grep defunct

 UID  PID **PPID** C STIME TTY TIME     CMD
 1000 637  27872   0 Oct12 ?   00:00:04 [chrome] <defunct>

看看谁是父母: ps ax | grep 27872

如果您愿意,可以杀死父母,而不再存在的父母将会消失。 kill -9 27872

有关更多技术性推理,请参阅JF Sebastian的答案。


1

除了@Paddington的答案外,我还将此功能添加到了bashrc中以便快速检查:

defunct(){
    echo "Children:"
    ps -ef | head -n1
    ps -ef | grep defunct
    echo "------------------------------"
    echo "Parents:"
    ppids="$(ps -ef | grep defunct | awk '{ print $3 }')"
    echo "$ppids" | while read ppid; do
        ps -A | grep "$ppid"
    done
}

它输出如下内容:

儿童:
UID PID PPID C STIME TTY TIME CMD
用户25707 25697 0 Feb26 pts / 0 00:00:00 [sh] 
用户30381 29915 0 11:46 pts / 7 00:00:00 grep已终止
------------------------------
父母:
25697点/ 0 00:00:00 npm
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.