Как убить зомби-процесс

184

Я запустил свою программу на переднем плане (программа-демон), а затем убил ее kill -9, но у меня остался зомби, и я не смог убить его kill -9. Как убить зомби-процесс?

Если зомби - мертвый процесс (уже убитый), как я могу удалить его из вывода ps aux?

root@OpenWrt:~# anyprogramd &
root@OpenWrt:~# ps aux | grep anyprogram
 1163 root      2552 S    anyprogramd
 1167 root      2552 S    anyprogramd
 1169 root      2552 S    anyprogramd
 1170 root      2552 S    anyprogramd
10101 root       944 S    grep anyprogram
root@OpenWrt:~# pidof anyprogramd
1170 1169 1167 1163
root@OpenWrt:~# kill -9 1170 1169 1167 1163
root@OpenWrt:~# ps aux |grep anyprogram
 1163 root         0 Z    [anyprogramd]
root@OpenWrt:~# kill -9 1163
root@OpenWrt:~# ps aux |grep anyprogram
 1163 root         0 Z    [anyprogramd]
MOHAMED
источник
2
Что ps -o ppid 1163говорит? То есть кто является родителем 1163? Это процесс, который должен быть прекращен.
Уильям Перселл

Ответы:

250

Зомби уже мертв, поэтому вы не можете его убить. Чтобы убрать зомби, его должен ждать его родитель, поэтому убийство родителя должно сработать, чтобы уничтожить зомби. (После того, как родитель умирает, зомби будет унаследован pid 1, который будет ждать его и очистить свою запись в таблице процессов.) Если ваш демон порождает детей, которые становятся зомби, у вас есть ошибка. Ваш демон должен замечать, когда его дети умирают, и waitпо ним определять свой статус выхода.

Пример того, как вы можете отправить сигнал каждому процессу, который является родителем зомби (обратите внимание, что это очень грубый процесс и может убить процессы, которые вы не намереваетесь. Я не рекомендую использовать этот тип кувалды):

# Don't do this.  Incredibly risky sledge hammer!
kill $(ps -A -ostat,ppid | awk '/[zZ]/ && !a[$2]++ {print $2}')
Уильям Перселл
источник
1
Если зомби - мертвый процесс (уже убитый), как я могу удалить его из вывода ps aux?
MOHAMED
186
Зомби должен ждать его родитель. Найдите своего родителя и выясните, почему этот родитель не обращает внимания на своих детей, затем подайте жалобу в социальные службы. ;)
Уильям Перселл
1
Предполагая, что у вас есть процесс, производящий много зомби, имеет смысл 'uniq' идентификаторы:kill $(ps -A -ostat,ppid | awk '/[zZ]/{print $2}' | sort -u)
ankon
2
как правило, вы можете найти родителя в PPidряду, если выcat /proc/<pid>/status
Даниэль Андрей Минкэ
2
Просто представьте, что не-айтишники приходят сюда и читают это. Псих.
ZitRo
68

Вы можете очистить процесс зомби, убив его родительский процесс с помощью следующей команды:

kill -HUP $(ps -A -ostat,ppid | grep -e '[zZ]'| awk '{ print $2 }')
Кришна Мурти
источник
6
Эта команда очищает зомби от таблицы процессов, но она не «убивает» зомби. Зомби уже мертв.
Уильям Перселл
8
Это grepне обязательно. ps ... | awk '/[zZ]/{print $2}'
Уильям Перселл
2
AFAICS, эта команда не убивает зомби, но отправляет SIGHUP своему родительскому процессу (предположительно, убивая родителя, если он не обрабатывает SIGHUP, и заставляя зомби переставить init, как описано в предыдущем ответе). Так что будьте осторожны с этой командой, она может убить то, чего вы не ожидали ...
Маттис Коойман
1
Это не сработало для меня. я сделал "kill -HUP processID", и процесс все еще там, как зомби
kommradHomer
1
@WilliamPursell, когда вы отвечаете на вопрос, опишите, пожалуйста, последствия использования командной строки и то, что она делает явно, потому что она убивает все программы, запущенные на компьютере.
Далек
39

Я попытался:

ps aux | grep -w Z   # returns the zombies pid
ps o ppid {returned pid from previous command}   # returns the parent
kill -1 {the parent id from previous command}

это будет работать :)

Мухаммед Рафи
источник
В моем случае зомби создавался с помощью сценария запуска и программы, которая не была четко удалена, поэтому я очистил ее.
Мухаммед Рафи
1
Работал на меня. Это будет работать в определенных случаях, когда процесс перестал быть порожден процессом уничтожения пыльников.
Эрик С. Буллингтон
2
Я проверил, что родительский процесс, прежде чем убить его. И я просто убил его, используя -9 вместо -1: kill -9 {идентификатор родителя}
Али
Я также должен был использовать -9, чтобы убить моего вместо -1
Майкл Смит
28

Нашел по адресу http://www.linuxquestions.org/questions/suse-novell-60/howto-kill-defunct-processes-574612/

2) Вот отличный совет от другого пользователя (Thxs Bill Dandreta): иногда

kill -9 <pid>

не убьет процесс. Бегать

ps -xal

4-е поле - родительский процесс, убейте всех родителей зомби, и зомби умрет!

пример

4 0 18581 31706 17 0 2664 1236 wait S ? 0:00 sh -c /usr/bin/gcc -fomit-frame-pointer -O -mfpmat
4 0 18582 18581 17 0 2064 828 wait S ? 0:00 /usr/i686-pc-linux-gnu/gcc-bin/3.3.6/gcc -fomit-fr
4 0 18583 18582 21 0 6684 3100 - R ? 0:00 /usr/lib/gcc-lib/i686-pc-linux-gnu/3.3.6/cc1 -quie

18581, 18582, 18583Зомби -

kill -9 18581 18582 18583

не имеет никакого эффекта

kill -9 31706

удаляет зомби.

Sergio
источник
3
ну, это просто убило initменя, и теперь я ничего не могу сделать и вынужден перезапускаться ... процесс зомби - это Java, занимающий 3,4 ГБ из 4 ГБ ОЗУ
Tcll
22

Я попытался

kill -9 $(ps -A -ostat,ppid | grep -e '[zZ]'| awk '{ print $2 }')

и это работает для меня.

Джеффри
источник