【问题标题】:zombie process can't be killed僵尸进程不能被杀死
【发布时间】:2011-09-14 05:03:51
【问题描述】:

有没有办法杀死僵尸进程?我试过调用exit 来终止进程,甚至向进程发送SIGINT 信号,但似乎没有什么可以杀死它。我正在为 Linux 编程。

【问题讨论】:

标签: c linux zombie-process


【解决方案1】:

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

使用ps faux 获得一个显示父/子关系的运行进程的漂亮层次树。

【讨论】:

  • 它实际上允许它被init收割。
【解决方案2】:

僵尸进程是其父进程尚未等待的进程 ID(以及相关的终止状态和资源使用信息)。消除它的唯一方法是让其父级等待它(有时这可以通过手动向父级发送SIGCHLD 来实现,如果父级只是有问题并且有竞争条件而错过了等待的机会)但是通常,除非您强行终止父级,否则您会很不走运。

编辑:另一种方法,如果您绝望并且不想杀死父级,则使用 gdb 附加到父级并在僵尸子级上强制调用waitpid

【讨论】:

    【解决方案3】:

    参见unix-faqs“我如何摆脱顽固的僵尸进程?”

    你不能杀死僵尸,因为它们已经死了。但是如果你有太多的僵尸然后杀死父进程或重新启动服务。

    你可以尝试使用它的pid杀死僵尸进程

    kill -9 pid
    

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

    【讨论】:

    • 不仅不能保证杀死僵尸进程。 kill -9 永远无法杀死僵尸进程。
    【解决方案4】:

    僵尸进程已经死了,所以它们不能被杀死,只能被收割,这必须由它们的父进程通过wait*() 来完成。这通常称为child reaper 成语,在SIGCHLD 的信号处理程序中:

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

    【讨论】:

    • 我必须在这个答案中使用zombiedeadkilledchild reaper :)
    • 此代码不正确。如果你把它放在你的 SIGCHLD 处理程序中,你可能会被阻塞并且永远不会返回。
    • @R..:您应该使用支持 WNOHANGwait() 变体之一
    • 您也可以通过signal(SIGCHLD, SIG_IGN) 让父进程忽略子进程。子进程一退出就消失(不留下僵尸),因为父进程已对其子进程的健康缺乏兴趣。
    【解决方案5】:

    kill -17 ZOMBIE_PID

    kill -SIGCHLD ZOMBIE_PID

    可能会起作用,但就像其他人所说的那样,它正在等待父母打电话给wait(),所以除非父母没有收割而死,并且由于某种原因卡在那里你可能不想杀死它。

    【讨论】:

    • 但我认为这是错误的,您可能必须将其发送给父母,idk
    【解决方案6】:

    这是我创建的用于杀死所有僵尸进程的脚本。它使用 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 上运行:warning: /tmp/zombie_slayer.txt: No such file or directory
    猜你喜欢
    • 2013-06-01
    • 2014-06-19
    • 1970-01-01
    • 1970-01-01
    • 2015-04-12
    • 1970-01-01
    • 2011-04-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多