chrome浏览器没有响应,因此我尝试杀死它,但并没有消失,而是在进程右侧显示了<defunct>,并且没有被杀死:



<defunct>是一个进程,为什么它没有被杀死?

评论

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

stackoverflow.com/questions/356722/…

#1 楼

从您的输出中,我们看到一个“已终止”,这意味着该进程已完成其任务或已被破坏或杀死,但其子进程仍在运行,或者这些父进程正在监视其子进程。
要终止此进程这种过程,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>
    1000      1808      1777       0    Oct04     ?        00:00:00 [zeitgeist-datah] <defunct>

然后kill -9 637 27872,然后通过ps -ef | grep defunct验证已终止进程。

评论


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

– jfs
2014年2月27日在20:58

如果ppid为1(初始化)怎么办?假设我只需要等待?

–吕克
2014年5月6日5:42



要自动执行终止操作,您也可以执行此操作(可能需要更改要从输出剪切的字节):ps -ef | grep已停用| grep -v grep |切-b8-20 | xargs杀死-9

–沃伦
15年1月21日在19:34

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

– Thor84no
16年7月26日在11:35

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

– Mike S
2016年9月1日14:50在

#2 楼

手册页ps(1)说:


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


您不能杀死它,因为它已经死了。剩下的唯一内容是进程表中的条目:


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


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


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


评论


“除非有很多这样的过程,否则这样做不会有任何危害”。这不是真的这些已失效的进程仍可以保持文件句柄打开(例如锁定文件)和打开端口。据我所知,有时没有系统重新启动就无法保存这些进程。

–斯科特
19年11月1日在20:10

@斯科特:为什么您认为无效的进程会使文件句柄保持打开状态?您是否有指向docs的链接,该脚本可以证明这种行为?

– jfs
19年11月5日在18:46

不幸的是,除了我已经看到它发生的事实外,我没有任何证据,而且我不知道下一次其中一个过程将再次陷入困境以进行复制。最近,我在文件上使用“ lsof”进行了验证,确认该文件是否与我已退出进程的进程相同的pid保持打开状态。以前,我(使用netstat / lsof)看到我已退出运行的进程仍然保持它正在监听的端口。我已经在init.d脚本中构建了防御机制,等待重新启动时清除已消失的进程,以便新进程可以绑定端口,这已经足够了。如果我复制将截图

–斯科特
19年11月6日在13:08

@Scott:您提到的问题似乎与进程成为僵尸有关,因为我感到惊讶的是,死进程可能会使文件句柄保持打开状态。让我们避免毫无根据的误导性主张

– jfs
19年11月7日在10:28

@Scott:僵尸进程(不仅死了)与“端口保持打开状态”之间是否真的存在联系? (网络资源可能会超过一个进程的事实这一点并没有受到idea.popcount.org/2019-09-20-when-tcp-sockets-refuse-to-die的质疑)

– jfs
19年11月10日在6:38

#3 楼

扩展Paddington的答案。.

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

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的答案以获取更多技术推理。

#4 楼

添加到@Paddington的答案后,我将此功能添加到了bashrc中以进行快速检查:

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


它输出的内容如下:

Children:
UID        PID  PPID  C STIME TTY          TIME CMD
user     25707 25697  0 Feb26 pts/0    00:00:00 [sh] 
user     30381 29915  0 11:46 pts/7    00:00:00 grep defunct
------------------------------
Parents:
25697 pts/0    00:00:00 npm


#5 楼

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

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

first_parent_of_first_dead_kid=$(ps -ef | grep [d]efunct | awk '{print }' | 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


#6 楼

我通过

从终端启动它们并意外地创建了<defunct>进程,然后又意外地将它们置于后台(Ctrl + Z),并以某种方式终止了程序。

解决方案是在每个打开的终端窗口中尝试命令fg
然后,已消失的进程消失。