процесс зомби нельзя убить

есть ли способ убить процесс зомби? Я пытался дозвониться exit чтобы убить процесс и даже отправить SIGINT сигнал процессу, но кажется, что ничто не может его убить. Я программирую для Linux.

6 ответов


процессы зомби уже мертвы, поэтому их нельзя убить, их можно только пожинать, что должно быть сделано их родительским процессом через wait*(). Это обычно называется child reaper идиома, в обработчике сигнала для SIGCHLD:

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

вот сценарий, который я создал, чтобы убить все процессы зомби. Он использует отладчик 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 }'`
  zombieid=`echo $LINE | awk '{print }'`
  verifyzombie=`echo $LINE | awk '{print }'`

  # 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 "***********************************************************"

наслаждайтесь.


зомби-процесс-это идентификатор процесса (и связанная с ним информация о состоянии завершения и использовании ресурсов), которого еще не ждал родительский процесс. Единственный способ устранить его-заставить его родителя ждать его (иногда это может быть достигнуто путем отправки SIGCHLD родителю вручную, если родитель был просто багги и имел состояние гонки, где он пропустил шанс подождать), но обычно вам не повезло, если вы принудительно не прекратите родитель.

Edit: другой способ, если вы в отчаянии и не хотите убивать родителя, это прикрепиться к родителю с помощью gdb и принудительно вызвать waitpid на ребенка-зомби.


если я правильно помню, убийство родителя процесса зомби позволит процессу зомби умереть.

использовать ps faux чтобы получить хорошее иерархическое дерево ваших запущенных процессов, показывающих отношения родитель / ребенок.


kill -17 ZOMBIE_PID

или

kill -SIGCHLD ZOMBIE_PID

возможно, будет работать, но, как все остальные сказали, он ждет родительского звонка wait() поэтому, если родитель не умирает без жатвы, и он застрял там по какой-то причине, вы, возможно, не захотите его убить.


посмотреть в Unix-часто задаваемые вопросы " как мне избавиться от зомби-процессов, которые упорствуют?"

вы не можете убить зомби, так как они уже мертвы. Но если у вас слишком много зомби, то убейте родительский процесс или перезапустите службу.

вы можете попытаться убить процесс зомби, используя его pid

kill -9 pid

обратите внимание, что kill -9 не гарантирует, чтобы убить процесс зомби