Форкинг для уточнения петли

Я видел много примеров разветвления циклов for здесь, но не много разъяснений о том, как он делает то, что делает. Давайте использовать этот простой пример из ответа Как использовать Fork() для создания только 2 дочерних процессов? В качестве примера.

for (i = 0; i < n; ++i) {
    pid = fork();
    if (pid) {
        continue;
    } else if (pid == 0) {
        break;
    } else {
        printf("fork error\n");
        exit(1);
    }
}

Большинство примеров, которые я видел, следуют этому общему формату. Но то, что я не понимаю, как это предотвращает разветвление дочерних процессов? Насколько я понимаю, каждый созданный ребенок тоже должен пройти этот цикл. Но fork() вызывается в самом начале цикла for, и затем происходит 3 сравнения. Может ли кто-нибудь объяснить, как, хотя кажется, что дети вызывают функцию fork(), цикл for по-прежнему гарантирует, что только родитель может создавать детей?

5 ответов

Решение

Ребенок начинается на линии после fork, fork возвращается 0 для ребенка. В вашем примере ребенок пошел бы в pid == 0 блок и break вне for петля.

После fork все точно так же для дочернего и родительского элемента (включая следующую команду для выполнения и значения переменных). Единственное отличие - это возвращаемое значение из fork (0 для ребенка, и пид ребенка для родителя).

Когда fork возвращается, фактически возвращается дважды: один раз родителю и один раз ребенку. Он возвращает 0 дочернему элементу и возвращает pid дочернего элемента родительскому элементу.

if Затем блок определяет, какой процесс вернулся. В родительском процессе if (pid) оценивается как истина, поэтому он выполняет continue и прыгает на вершину петли.

В дочернем процессе, if (pid) оценивается как ложное, то if (pid == 0) оценивается как истина, поэтому он выполняет break выпрыгнуть из петли. Таким образом, ребенок больше не разветвляется.

Но то, что я не понимаю, как это предотвращает разветвление дочерних процессов?

fork() возвращает 0 у ребенка. В вашем примере кода, который заставляет ребенка break вне цикла вместо выполнения другой итерации, поэтому дети на самом деле не вызывают fork(),

После проверки почему эта программа печатает "разветвленный!" 4 раза?, мне кажется, почему.

как это предотвращает разветвление дочерних процессов?

if (pid) {
  continue;
}

Вы видите, когда создается ребенок, а затем выполняет его код и вызывает fork() на этой стадии он становится родителем, таким образом pid будет 0.

Пытаться man 2 fork , Fork(2) возвращает другое значение для родителя и потомка, родитель получает pid и ребенок получает 0,

Другие вопросы по тегам