Почему процесс / программа становится зомби?

13

Если сценарий работает нормально из командной строки, то почему этот же сценарий переходит в состояние зомби после запуска через cron и как вы будете устранять неполадки?

Вот следующий реальный пример:

[root@abc ~]# ps ax | grep Z
23880 ?        Zs     0:00 [checkloadadv.sh] <defunct>
23926 pts/0    S+     0:00 grep Z
[root@abc ~]# strace -p 23880
attach: ptrace(PTRACE_ATTACH, ...): Operation not permitted
[root@abc ~]# pstree | grep  checkload
init-+-crond---crond-+-checkloadadv.sh
[root@abc ~]# bash /usr/bin/checkloadadv.sh
System Load is OK : 0.05
Рахул Патил
источник
Устранение неполадок происходит, когда есть проблема. Зомби не проблема.
Жиль "ТАК - перестань быть злым"
@ Жиль, ты прав, но мне нужно заботиться и выяснять, как их предотвратить? что вы думаете ?
Рахул Патил
Они не проблема, поэтому нет, вам не нужно заботиться.
Жиль "ТАК - перестань быть злым"

Ответы:

21

введите описание изображения здесь

Как настоящий зомби, процесс зомби не может быть убит, потому что он уже мертв.

Как это происходит

Когда в Linux / Unix процесс умирает / завершается, вся информация из процесса удаляется из системной памяти, остается только дескриптор процесса. Процесс попадания в состояние Z (зомби). Его родительский процесс получает сигнал от ядра: SIGCHLDэто означает, что один из его дочерних процессов завершается, прерывается или возобновляет работу после прерывания (в нашем случае он просто завершается).

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

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

Рассвет мертвецов

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

Так что, если они в огромных группах, они очень опасны (как во многих фильмах демонстрируется очень хорошо)

Как мы можем защитить себя от орды зомби?

Сработал выстрел в голову, но я не знаю команду для этого (SIGKILL не сработает, потому что процесс уже мертв).

Ну, вы можете отправить SIGCHLD через kill родительскому процессу, но когда он игнорирует этот сигнал, что тогда? Ваша единственная возможность - убить родительский процесс, и процесс инициации «принимает» зомби. wait()Инициал периодически вызывает системный вызов, чтобы убрать своих детей-зомби.

В твоем случае

В вашем случае вы должны отправить SIGCHLD процессу crond:

root@host:~# strace -p $(pgrep cron)
Process 1180 attached - interrupt to quit

Затем из другого терминала:

root@host:~$ kill -17 $(pgrep cron)

Выход:

restart_syscall(<... resuming interrupted call ...>) = ? ERESTART_RESTARTBLOCK (To be restarted)
--- SIGCHLD (Child exited) @ 0 (0) ---
wait4(-1, 0x7fff51be39dc, WNOHANG, NULL) = -1 ECHILD (No child processes) <-- Here it happens
rt_sigreturn(0xffffffffffffffff)        = -1 EINTR (Interrupted system call)
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=1892, ...}) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGCHLD, NULL, {0x403170, [CHLD], SA_RESTORER|SA_RESTART, 0x7fd6a7e9d4a0}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
nanosleep({42, 0}, ^C <unfinished ...>
Process 1180 detached

Вы видите, что wait4()системный вызов возвращает -1 ECHILD, что означает, что там нет дочерних процессов. Итак, вывод таков: cron реагирует на системный вызов SIGCHLD и не должен форсировать апокалипсис.

хаос
источник
1
Что, никаких крикетных бит и пластинок?
Алексиос
-3

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

Sandeep
источник
7
Не правда, они просто будут перекрашены. У процессов зомби не было вызова waitpid.
Крис Даун
Возможно, он говорил о родительских и дочерних процессах; дочерний процесс становится «сиротой», когда его родитель «умирает».
Barun