Процесс-зомби — это дочерний процесс, который завершился, но не дождался родительского процесса. Дочерние процессы обычно создаются с помощью fork:
int pid = fork();
if (pid < 0) {
// fork failed
} else if (pid == 0) {
// this is the child process
}
// this is the parent
fork
возвращает 0 дочернему процессу и положительный pid родительскому процессу. Возможны два случая прекращения их действия:
дочерний процесс завершается раньше родительского, затем дочерний процесс становится «зомби» до тех пор, пока родитель не вызовет функции семейства ожидания, чтобы получить статус выхода дочернего процесса.
родительский выход перед дочерним, тогда дочерний процесс будет переподчинен процессу инициализации, процесс инициализации вызовет ожидание после выхода дочернего элемента. Это работает, потому что родитель получит сигнал SIGCHLD, когда его потомок выйдет, и он может вызвать ожидание в обработчике сигнала. Так что в этом случае зомби создаваться не будет.
Также обратите внимание, что posix определяет, что зомби не создаются, если родитель игнорирует SIGCHLD:
В POSIX.1-2001 указано, что если для SIGCHLD задано значение SIG_IGN или установлен флаг SA_NOCLDWAIT для SIGCHLD (см. ) будет блокироваться до тех пор, пока не будут завершены все дочерние процессы, а затем завершится сбоем, когда для errno будет установлено значение ECHILD. (Исходный стандарт POSIX оставил поведение при установке SIGCHLD в SIG_IGN неопределенным. Обратите внимание, что хотя по умолчанию для SIGCHLD установлено значение «игнорировать», явная установка для SIG_IGN приводит к другому обращению с дочерними процессами-зомби.)
Для двух случаев в ОП:
// Case 1
while(fork()) // same as while(fork() != 0)
;
exit(0);
// Case 2
while(!fork()) // same as while(fork() == 0)
;
exit(0);
1-й код продолжает разветвление в родительском элементе, независимо от того, успешно он или нет, и результирующие дочерние элементы немедленно завершатся, поскольку возвращаемое значение будет равно 0. Поскольку родитель зависает в цикле while, независимо от того, успешно или неудачно вилка (только вилка возвращает 0 для детей), все дети станут зомби.
Для 2-го случая родитель завершается немедленно, когда fork возвращается, но потомок будет продолжать разветвление, и этот ребенок снова сделает то же самое, то есть он выйдет немедленно, а созданный им ребенок продолжит разветвление. В этом случае, с момента выхода родителя, все его дочерние элементы будут переназначены для процесса инициализации, в результате зомби не будут созданы.
person
fluter
schedule
27.04.2016
wait()
и другие), которая блокирует получение уведомления. У вас будет зомби каждый раз, когда вы создаете потомка, и этот потомок завершается, и вы не завершаете и не вызываете одну из функций ожидания. - person mah   schedule 27.04.2016