Почему дочерний процесс все еще жив после родительского процесса в Linux?
Кто-то сказал мне, что когда вы убили родительский процесс в Linux, ребенок умрет.
Но я в этом сомневаюсь. Поэтому я написал два сценария bash, где father.sh
будет вызывать child.sh
Вот мой script:
![enter image description here]()
Теперь я запустил bash father.sh
, вы можете проверить его ps -alf
![enter image description here]()
Затем я убил father.sh
на kill -9 24588
, и я догадался, что дочерний процесс должен быть прекращен, но, к сожалению, я ошибся.
![enter image description here]()
Может ли кто-нибудь объяснить, почему?
ТНХ
Ответы
Ответ 1
Нет, когда вы убиваете только процесс, он не будет убивать детей.
Вы должны отправить сигнал в группу процессов, если хотите, чтобы все процессы для данной группы получали сигнал
kill -9 -parentpid
В противном случае сироты будут связаны с init
, как показано на третьем скриншоте (PPID для ребенка стал 1).
Ответ 2
Люди собираются проголосовать за это, но принятый ответ false. Как правило, убийство родителя также убивает ребенка.
Причина, по которой вы видите, что ребенок все еще жив после убийства отца, состоит в том, что ребенок только умрет после того, как он захочет справиться с событием SIGKILL. Он не должен справляться с этим сразу. Ваш script запускает команду sleep(), которая не проснется, чтобы обрабатывать любые события до завершения сна.
Почему PPID # 1? Родитель умер и больше не находится в таблице процессов. child.sh не связано необъяснимо для init сейчас. У этого просто нет родителя. Говорить, что он связан с init, создается впечатление, что если мы каким-то образом оставим init, этот init будет иметь контроль над завершением процесса. Это также создает впечатление, что убийство родителя сделает дедушку и бабушку владельцем ребенка. Оба не соответствуют действительности. Этот дочерний процесс все еще существует в таблице процессов и работает, но никаких новых событий, основанных на его идентификаторе процесса, не будет обрабатываться до тех пор, пока он не обработает SIGKILL. Это означает, что ребенок - пред зомби, ходячий мертвец, в опасности быть помеченным.
Убийство в группе процессов различно и используется для убийства братьев и сестер, а родитель - группой процессов #. Вероятно, также важно отметить, что "убийство процесса" не "убивает" как таковое, по-человечески, где вы ожидаете, что процесс будет уничтожен, и вся память вернется, как будто этого никогда не было. Он просто отправляет определенное событие, среди многих, процессу его обработки. Если процесс не справится с этим должным образом, через некоторое время ОС придет и "очистит" принудительно.
Это (убийство) происходит не сразу, потому что ребенок (или даже родительский) мог написать что-то на диск и ждать завершения ввода-вывода или выполнения другой важной задачи, которая может поставить под угрозу стабильность системы или файл целостность.
Ответ 3
- bash: kill: (-123) - Нет такого процесса
В интерактивном сеансе Terminal.app число идентификаторов группы процесса и номер группы фонового процесса различаются по дизайну, когда включен режим управления работой/мониторинга. Другими словами, если вы выполняете команду в сеансе Terminal.app с включенным контролем заданий, то pid $!
фонового процесса на самом деле представляет собой новый идентификатор группы процессов (pgid).
В script, не имеющем управления заданиями, однако, это может быть не так! Pid фонового процесса может быть не новым pgid, а нормальным pid! И вот что вызывает сообщение об ошибке -bash: kill: (-123) - No such process
, пытаясь убить группу процессов, но только указывая нормальный pid (вместо pgid) команде kill
.
# the following code works in Terminal.app because $! == $pgid
{
sleep 100 &
IFS=" " read -r pgid <<EOF
$(ps -p $! -o pgid=)
EOF
echo $$ $! $pgid
sleep 10
kill -HUP -- -$!
#kill -HUP -- -${pgid} # use in script
}
Ответ 4
pkill -TERM -P <ProcessID>
Это убьет как родителя, так и ребенка