Смерть родителей не убивает детей в программе C на Linux
Смотрите код ниже:
#include<stdio.h>
void main()
{
int pid = fork();
if(pid==0)
{
while(1);
}
else
{
while(1);
}
}
Запустите этот код из терминала 1:
Перейдите к терминалу 2 и проверьте процессы на терминале 1:
hduser@pc4:~$ ps -ft /dev/pts/1
UID PID PPID C STIME TTY TIME CMD
hduser 3824 3505 0 17:20 pts/26 00:00:00 bash
hduser 4007 3824 21 17:33 pts/26 00:00:01 ./a.out
hduser 4008 4007 22 17:33 pts/26 00:00:02 ./a.out
hduser@pc4:~$
Здесь два бегущих. Теперь убейте родителя 4007.
hduser@pc4:~$ kill -9 4007
hduser@pc4:~$ ps -ft /dev/pts/26
UID PID PPID C STIME TTY TIME CMD
hduser 3824 3505 0 17:20 pts/26 00:00:00 bash
hduser 4008 2077 24 17:33 pts/26 00:00:29 ./a.out
hduser@pc4:~$
Примечание 4008 все еще работает, и теперь оно является дочерним по отношению к 2077(init --user).
Мое сомнение:
- Почему ребенок не убит родителем до смерти родителей?
- Обычно, если мы запускаем любой процесс из терминала (bash) без "nohup" и убиваем bash, тогда дочерний элемент bash убивается. Как реализовать это поведение в нашей C-программе?
- Я думал, что поведение по умолчанию состоит в том, что родитель убивает своего ребенка перед смертью, и мы должны вызвать wait(), чтобы преодолеть это поведение. Но я был неправ. Тогда какова цель wait()?
Я использую Ubuntu 14 с ядром 3.13.0-52-generic.
2 ответа
В системе Linux / UNIX процесс не умирает, если он не завершен или явно не уничтожен каким-либо другим процессом.
Что за wait
Системный вызов приостанавливает процесс до тех пор, пока один из его дочерних процессов не умрет. Вы также можете позвонить waitpid
, который ждет конкретного дочернего процесса, чтобы умереть.
Если у процесса есть управляющий терминал, и терминал выходит, любой процесс под этим управляющим терминалом уничтожается ОС. Вы можете использовать setsid
системный вызов для отсоединения процесса от его управляющего терминала, чтобы он мог жить в фоновом режиме даже после выхода пользователя из системы.
В Linux дочерний процесс не уничтожается, когда родитель умирает.
Вы можете написать обработчик сигнала для родителя, и в этом обработчике сигнала вы можете вызвать API для уничтожения дочернего процесса.
Системный вызов wait вызывается из родительского процесса, чтобы приостановить его, пока не завершится один из его дочерних процессов. Иначе ребенок станет зомби-процессом.