Как я могу убить процесс зомби, чей родитель PID = 0?
Часто при запуске LLDB в OSX отладчик время от времени дает сбой (это, кажется, является природой LLDB). Когда это происходит, я получаю процесс зомби (тот, который я отлаживал), который выглядит действительно странно. У него родительский PID = 0:
Мой процесс называется: работник
Вот вывод ps aux | grep worker
root 22785 0.0 0.0 0 0 ?? Z 3:48pm 0:00.00 (worker)
Как видите, у процесса есть PID, но у него нет родительского PID. Это ничего не делает
sudo kill -9 <pid>
На самом деле, ничто, кроме перезапуска, похоже, не избавится от этого. Как я могу убить такой процесс? Мне нужен процесс, чтобы умереть, потому что он держится на портах, которые мне нужны.
3 ответа
Ситуация такова, что пользователь не может очистить процесс зомби; ядро справится с этим, когда будет готово, если это возможно.
Как подробно описано в Mac OS X и iOS Internals,
это совершенно нормальное состояние, и каждый процесс обычно тратит бесконечно малое количество времени, прежде чем он успокоится с миром... Родители, которые переживают, но оставляют своих детей и переходят к другим вещам, будут прокляты, чтобы дети застряли в почти мертвом состоянии зомби. Зомби, по сути, совершенно мертвые.
Поскольку отладчик действует как родительский элемент для своего целевого процесса, который содержит сетевой порт, и отладчик вышел из строя, он оставляет целевой процесс в состоянии зомби. Проблема здесь - сбой отладчика.
Зомби - это имя, данное процессам, которые уже умерли. Поэтому они больше не работают и больше не потребляют системные ресурсы. Они перечислены только в таблице процессов, которая не может быть должным образом обновлена во время завершения процесса зомби. Это также причина, по которой они не назначены никаким значимым родителям.
Поэтому вы не можете убить зомби во второй раз (как уже следует из их названия, в отличие от того, что происходит в фильмах ужасов среднего уровня:-)). В большинстве операционных систем достаточно подождать некоторое время, чтобы процессы зомби исчезли из списка процессов. Или вы должны сделать перезагрузку, если вы не можете жить с этим.
Будьте уверены, зомби не причинят вам вреда.
Что нужно сделать, это присоединиться к работающему родителю. Init должен очистить эти процессы для вас.
Мы можем создать несуществующий процесс следующим образом:
bash$ (sleep 1 & exec /bin/sleep 5000) &
Теперь мы можем проверить наш несуществующий процесс:
$ ps -C sleep
PID TTY TIME CMD
22582 pts/3 00:00:00 sleep
22583 pts/3 00:00:00 sleep <defunct>
Таким образом, мы должны получить родительский идентификатор ребенка. В этом случае это легко, но если вы не знаете родителя, мы можем просто использовать ps -o ppid= 22583
Таким образом, когда у вас есть эта информация, вы можете прикрепить к родителю и call waitpid()
$ gdb
(gdb) attach 22582
(gdb) call waitpid(22583,0,0)
$1=22583
(gdb) detach
(gdb) quit
И мы видим, что несуществующий процесс очищается другим ps -C sleep
:
PID TTY TIME CMD
22582 pts/3 00:00:00 sleep
Надеюсь, это поможет.
редактировать: зомби не занимают ресурсы. Однако они действительно занимают место в таблице процессов ядра, если там больше нет места, то может быть невозможно запустить другой процесс.