Разветвление в цикле не работает как мысль

#c #loops #fork

#c #циклы #fork

Вопрос:

Я хочу, чтобы основной процесс запускался и создавал 4 подпроцесса. Как только они будут созданы, я хочу, чтобы основной процесс дождался их завершения.

Это весь мой код:

 #include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>


int main(){

    int i;
    int childID;
    int status;

    for (i=0;i<4;i  ){
        childID=fork();
        if (childID==0){
            printf("[%d] I the child, will sleepn", (int)getpid());
            sleep(1);
        }
    }

    if (!childID){
        wait(amp;status);
        printf("[%d] I the parent, have waited for my children!n", (int)getpid());
    }

    return 0;
}
 

Вместо этого я получаю следующее:

 ..
[8508] I the child, will sleep
[8503] I the parent, have waited for my children!
[8511] I the child, will sleep
[8510] I the child, will sleep
[8509] I the child, will sleep
[8520] I the child, will sleep
[8511] I the parent, have waited for my children!
[8510] I the parent, have waited for my children!
(prompt stuck)
 

Почему родительский файл распечатывается несколько раз, а не один раз, в конце концов?

Комментарии:

1. Ваш вывод не соответствует вашему коду. Исправьте это, пожалуйста

2. В коде, который вы нам дали, нет инструкции, которая печатает «Я, родитель, буду ждать своих детей!». Есть ли что-то еще в коде?

3. Помимо того факта, что ваши дочерние элементы тоже будут разветвляться, как упоминалось в ответах, вы также ждете только последнего разветвленного дочернего элемента, а не всех своих дочерних элементов.

4. Извините за это. Просто я поменял местами позиции wait() и printf в последнюю минуту и забыл также обновить выходные данные.

Ответ №1:

Это не родительский элемент, который записывает несколько раз, а первые 3 дочерних элемента. Когда вы fork , дочерние элементы получают точную копию процесса, включая его адресное пространство, стек, регистры, все. Это означает, что после первого fork и родительский, и новый дочерний элемент пройдут for еще 3 раза, создавая 3 новых дочерних элемента. Вы должны break выйти из for при выполнении в качестве дочерних элементов для получения желаемого эффекта:

     if (childID==0){
        printf("[%d] I the child, will sleepn", (int)getpid());
        sleep(1);
        break;
    }
 

Комментарии:

1. Я думал, что после запуска fork() будет выполняться только код после его запуска. Так как fork находится внутри цикла, я подумал, что, возможно, он обойдет весь цикл и продолжит после него..

Ответ №2:

Посмотрите на pid отпечатков. 8510 и 8511 являются дочерними элементами, а не исходным родительским элементом. Когда вы разветвляете цикл, дочерние элементы также находятся в этом цикле. Попробуйте поместить a break; после sleep(1).

Ответ №3:

Когда вы запускаете цикл, после того, как вы разветвляете, дочерний элемент спит во время первой итерации после его разветвления, но затем он разветвляет больше процессов. Поскольку childID это больше не 0 для этих процессов, не вызывайте wait, и поэтому они не получают своих дочерних элементов. Это означает, что когда все вызовы ожидания будут завершены, у вас все еще будут запущены процессы, поэтому терминал зависнет.