僵尸进程无法被终止。

9

有没有一种方法可以杀掉僵尸进程?我尝试过调用exit来结束进程,甚至向进程发送SIGINT信号,但似乎没有任何东西可以杀死它。我正在为Linux编程。


2
哦,我忘了开个玩笑:杀死僵尸的方法就是朝头部开枪。 - ninjalj
"kill PID" 什么情况下会失败? - Prince John Wesley
参见收割子进程意味着什么? - Steve Summit
6个回答

11

僵尸进程已经死亡,因此它们无法被杀死,只能通过其父进程通过wait*()来收割。这通常称为child reaper习语,在SIGCHLD的信号处理程序中使用:

while (wait*(... WNOHANG ...)) {
    ...
}

20
好的,我会尽力进行翻译。以下是需要翻译的内容:I got to use zombie, dead, killed and child reaper in this answer :)在这个答案中,我要使用“僵尸”、“死亡”、“杀死”和“小孩收割者”这些词。 :) - ninjalj
这段代码是不正确的。如果你将它放在你的 SIGCHLD 处理程序中,你会冒着阻塞和永远无法返回的风险。 - R.. GitHub STOP HELPING ICE
@R..:你应该使用支持“WNOHANG”的“wait()”变体之一。 - ninjalj
10
你还可以通过 signal(SIGCHLD, SIG_IGN) 让父进程忽略子进程的状态。当子进程退出时,由于父进程已经声明了不关心子进程的情况,所以该子进程会立即离开(不会留下僵尸进程)。 - unpythonic

4
这是我创造的一个脚本,能够消灭所有僵尸进程。它使用GDB调试器来附加到父进程并发送waitpid以杀死僵尸进程。这将使父进程保持运行并且只能消灭僵尸进程。
需要安装GDB调试器,并且您需要已登录以具有附加到进程的权限。此脚本在Centos 6.3上进行了测试。
#!/bin/bash
##################################################################
# Script: Zombie Slayer
# Author: Mitch Milner
# Date:   03/13/2013 ---> A good day to slay zombies
#
# Requirements: yum install gdb
#               permissions to attach to the parent process
#
# This script works by using a debugger to
# attach to the parent process and then issuing
# a waitpid to the dead zombie. This will not kill
# the living parent process.
##################################################################

clear
# Wait for user input to proceed, give user a chance to cancel script
echo "***********************************************************"
echo -e "This script will terminate all zombie process."
echo -e "Press [ENTER] to continue or [CTRL] + C to cancel:"
echo "***********************************************************"
read cmd_string
echo -e "\n"

# initialize variables
intcount=0
lastparentid=0

# remove old gdb command file
rm -f /tmp/zombie_slayer.txt

# create the gdb command file
echo "***********************************************************"
echo "Creating command file..."
echo "***********************************************************"
ps -e -o ppid,pid,stat,command | grep Z | sort | while read LINE; do
  intcount=$((intcount+1))
  parentid=`echo $LINE | awk '{print $1}'`
  zombieid=`echo $LINE | awk '{print $2}'`
  verifyzombie=`echo $LINE | awk '{print $3}'`

  # make sure this is a zombie file and we are not getting a Z from
  # the command field of the ps -e -o ppid,pid,stat,command
  if [ "$verifyzombie" == "Z" ]
  then
    if [ "$parentid" != "$lastparentid" ]
    then
      if [ "$lastparentid" != "0" ]
      then
        echo "detach" >> /tmp/zombie_slayer.txt
      fi
    echo "attach $parentid" >> /tmp/zombie_slayer.txt
    fi
    echo "call waitpid ($zombieid,0,0)" >> /tmp/zombie_slayer.txt
    echo "Logging: Parent: $parentid  Zombie: $zombieid"
    lastparentid=$parentid
  fi
done
if [ "$lastparentid" != "0" ]
then
  echo "detach" >> /tmp/zombie_slayer.txt
fi

# Slay the zombies with gdb and the created command file
echo -e "\n\n"
echo "***********************************************************"
echo "Slaying zombie processes..."
echo "***********************************************************"
gdb -batch -x /tmp/zombie_slayer.txt
echo -e "\n\n"
echo "***********************************************************"
echo "Script complete."
echo "***********************************************************"

享受。


在Ubuntu 14.04上无法运行:警告:/tmp/zombie_slayer.txt:没有这个文件或目录 - Fernando Correia

2
一种僵尸进程是指一个进程ID(以及相关的终止状态和资源使用信息),它还没有被其父进程等待。消除它的唯一方法是让其父进程等待它(有时如果父进程只是出现了错误,并且存在竞争条件错过等待机会的情况,可以通过手动向父进程发送SIGCHLD来实现),但通常情况下,除非强制终止父进程,否则你将毫无办法。 编辑:另一种方法是,如果你绝望并且不想杀死父进程,则可以使用gdb附加到父进程,并强制调用waitpid以等待僵尸子进程。

1

kill -17 ZOMBIE_PID

或者

kill -SIGCHLD ZOMBIE_PID

可能会起作用,但像其他人所说,它正在等待父进程调用wait(),因此除非父进程在没有收割的情况下死亡,并且由于某种原因被卡在那里,否则您可能不想杀死它。


2
但我认为这是错误的,你可能需要将其发送给父级,我不知道。 - loosecannon

0

如果我没记错的话,杀死僵尸进程的父进程将允许僵尸进程死亡。

使用ps faux可以获得您正在运行的进程的漂亮分层树,显示父/子关系。


2
它实际上允许init收获它。 - ninjalj

-2

查看unix-faqs "如何摆脱持续存在的僵尸进程?"

你无法杀死僵尸进程,因为它们已经死了。但如果你有太多的僵尸进程,那么可以杀死父进程或重新启动服务。

你可以尝试使用其pid来杀死僵尸进程。

kill -9 pid

请注意,kill -9 命令不能保证杀死僵尸进程。

7
kill -9 命令不仅不能保证杀死僵尸进程,而且永远也无法杀死僵尸进程。 - R.. GitHub STOP HELPING ICE

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接