Родительский процесс отслеживает статус завершения дочернего процесса. - PullRequest
0 голосов
/ 15 ноября 2018

Я читаю функции wait и waitpid и наткнулся на следующий текст:

Когда процесс завершается, нормально или ненормально, ядро ​​уведомляет родителя, отправляяSIGCHLD сигнал родителю.

Тогда родитель должен обработать завершение.

Я не совсем понимаю, почему родитель должен знать своего потомкапрекращено.Конечно, если ребенок уже закончил, он ушел и никогда не будет потреблять никаких ресурсов.

По какой причине родитель должен знать об этом?

1 Ответ

0 голосов
/ 15 ноября 2018

Если процесс запускает другие процессы, он обычно хочет отслеживать их состояние.

Когда дочерний процесс завершается, он почти полностью исчезает. Он превращается в процесс зомби, и для другого процесса (обычно родительского) хранится достаточно информации, чтобы почему прекратил (в основном, его код возврата).

Затем, когда родитель успешно выполняет wait для дочернего элемента, возвращается код возврата и очищаются последние остатки дочернего элемента.

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

sleep 3601 &
( sleep 3602 & )

Последний запускает дочернюю оболочку и, начиная с нее, запускает сон, затем дочерняя оболочка завершается, так что дочерний элемент получает новый родитель:

1 /sbin/init splash
|
+-- 1121 /usr/sbin/lightdm
    |
    +-- 1846 /usr/sbin/lightdm --session-child 12 19
        |
        +-- 2078 /sbin/upstart --user
        |
        +--- 29899 sleep 3602
        |
        +--- 2929 /usr/lib/gnome-terminal/gnome-terminal-server
             |
             +--- 2935 bash (my bash shell)
                  |
                  +--- 29891 sleep 3601

Здесь вы можете видеть, что один из sleep процессов по-прежнему имеет мою оболочку в качестве родителя, но другой был перемещен вверх по дереву процессов до upstart.

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


(a) Современные UNIX могут переопределить это с помощью вызова prctl() с аргументом PR_SET_CHILD_SUBREAPER. Это помечает процесс как подчиненный.

Затем, когда родитель умирает, суб-жнец первого кулака при переходе вверх по дереву процессов становится новым родителем его непосредственных потомков (с init, являющимся конечным жнецом).

На самом деле вы можете увидеть это в приведенном выше дереве процессов, где очевидно, что upstart сделал именно это. Это означает, что it был первым суб-жнецом, найденным при ходьбе по дереву, поэтому sleep, принадлежавший процессу, который умер, не достигал вплоть до init.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...