2017-01-31 3 views
1

Почему программа не заканчивается? Ребенок зависает после печати того, что он должен распечатать. Если родительский процесс спал вместо ребенка, это сработало бы, но почему? Я также попытался вызвать exit в конце каждого процесса, но с тем же результатом. Должен ли я всегда ждать окончания ребенка?Почему вилка висит?

int main(){ 

    int pid = fork(); 

    char s[100] = "Hello"; 

    if(pid > 0){ 
     printf("FIRST PRINT IN PARENT: %s\n", s); 
     strcat(s, " - PARENT"); 
     printf("SECOND PRINT IN PARENT: %s\n", s); 
    } 
    else if(pid == 0){ 
     printf("IMMEDIATELY IN CHILD: %s\n", s); 
     sleep(2); 
     printf("AFTER 2 SCONDS IN CHILD: %s\n", s); 
    } 
    return 0; 
} 
+1

Are вы * уверены * он "зависает"? Дело не в том, что терминал печатает выходные данные дочернего элемента и просто не отображает подсказку еще раз? Попробуйте нажать клавишу «Enter» и посмотреть, что произойдет. Кроме того, если вы внимательно посмотрите в своем терминале, вы, вероятно, увидите * подсказку перед последним выходом дочернего элемента. –

+1

Не вы, но ваш _shell_ ждет завершения процесса _parent_. Вам нужно будет удвоить fork, чтобы мгновенно восстановить приглашение оболочки. – Ctx

+0

Код работает для меня. Если вы подозреваете, что он «висит», он все еще отображается на выходе 'ps'? – cdarke

ответ

0

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

Источником проблем, которые вы наблюдали, является то, что ваш родительский процесс doens't wait для своего ребенка. Используйте системный вызов wait(2), например wait(0);, в родительском процессе.

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

1

Когда родительский выход завершен, он может отправить сигнал (SIGHUP) ребенку. Если это так, и если ребенок не поймает этот сигнал, ребенок умирает.

Исторически сложилось, что по умолчанию был отправлен процесс SIGHUP его детям при его выходе. В настоящее время многие дистрибутивы Linux не отправляют SIGHUP по умолчанию.

Я пробовал ваш код на RHEL, и детский процесс не был убит. Таким образом, родительские матрицы и управление возвращаются в оболочку. Ребенок продолжает и печатает второй результат через 2 секунды.

Если ребенок действительно принимает SIGHUP, он не будет висеть. Он умирает, и окончательная строка никогда не печатается.

В Linux, вы можете включить SIGHUP через prctl системного вызова:

#include <sys/prctl.h> 
prctl(PR_SET_PDEATHSIG, SIGHUP); 

Похожие вопросы: how-to-make-child-process-die-after-parent-exits

Смежные вопросы