процесс зомби нельзя убить
есть ли способ убить процесс зомби? Я пытался дозвониться 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 не гарантирует, чтобы убить процесс зомби