<defunct>
,并且没有被杀死:<defunct>
是一个进程,为什么它没有被杀死?#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
。然后,已消失的进程消失。
评论
接受的答案提到“ kill -9 PID不起作用”。这是部分正确的:实际上,没有杀戮将起作用。此外,-9应该用作最后的选择。默认情况下,父进程的默认杀死将在99%的时间内杀死它并收获所有子进程。 “默认终止”是SIGTERM(-15)。我鼓励-9(SIGKILL)的粉丝阅读stackoverflow.com/questions/690415/…stackoverflow.com/questions/356722/…