2015-12-21 3 views
1

Я пытаюсь понять следующее, где только дочерний процесс создает детей.fork() и exit() в C

int main(int argc, char **argv) { 
    int i; 
    int n; 
    int num_kids; 

    if (argc != 2) { 
     fprintf(stderr, "Usage: forkloop <numkids>\n"); 
     exit(1); 
    } 

    num_kids = atoi(argv[1]); 

    for (i = 0; i < num_kids; i++) { 
     n = fork(); 
     if (n > 0) { 
      printf("pid = %d, ppid = %d, i = %d\n", getpid(), getppid(), i); 
      if (wait(NULL) == -1) { 
       perror("wait"); 
      } 
      exit(0); 
     } else { 
      printf("pid = %d, ppid = %d, i = %d\n", getpid(), getppid(), i); 
     } 
    } 
    return 0; 
} 

Am I прямо в понимании того, что, в конце каждого цикла, выходов родительского процесса, и ребенок становится новым родителем? Причина в том, что оператор exit() завершает родительский процесс? Кроме того, wait() в родительском, дождитесь окончания его дочернего элемента, каждой итерации цикла и только потом выйти? Но потом ребенок никогда не выходит, так что, когда вступает в игру заявление ожидания?

+0

Предложите вам запустить программу и посмотреть, что произойдет. Добавьте еще несколько инструкций 'printf', если это вам поможет. Это лучший способ понять это. Но да, 'wait' ждет выхода ребенка. Последний созданный ребенок не будет вызывать 'fork' из-за того, что цикл' for' достигает конца. Таким образом, он выйдет, достигнув конца 'main', а затем его родитель выйдет и так далее по цепочке. – kaylum

+0

В настоящее время у вас есть родитель, ожидающий, когда его первый ребенок умрет, а затем выйдет, а ребенок продолжит выполнение следующей итерации цикла (как если бы он был родителем). Так что да, ваше описание того, что происходит, в основном правильное, за исключением того, что дети умирают. Основная проблема заключается в том, что родитель не выходит сразу - все его потомство (его дети детей детей и т. Д.) Должны умереть. Вы можете улучшить отслеживаемость, сообщив о процессе, который выходит непосредственно перед 'return 0;' в 'main()'. Было бы неплохо напечатать дочерний PID в родительском коде. –

ответ

3

Я правильно понял, что в конце каждого цикла родительский процесс завершает процесс, а ребенок становится новым родителем? Причиной является оператор exit(), который завершает родительский процесс?

Да, но процесс не сразу умирает. Каждый «родитель» вызывает wait() и ждет завершения дочернего процесса.

Кроме того, не ждать() в родительском, ждать его ребенка прекратить, каждую итерацию цикла и только потом выйти?

Да. Это означает, что «родительские» процессы умирают в обратном порядке. Это означает, что последний процесс умирает последним.

Но, тогда ребенок никогда не выйдет, поэтому когда вступает в игру заявление ?

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