Форкинг в цикле не работает как думал - PullRequest
0 голосов
/ 22 октября 2011

Я хочу запустить основной процесс и создать 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 sleep\n", (int)getpid());
            sleep(1);
        }
    }

    if (!childID){
        wait(&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)

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

Ответы [ 3 ]

3 голосов
/ 22 октября 2011

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

    if (childID==0){
        printf("[%d] I the child, will sleep\n", (int)getpid());
        sleep(1);
        break;
    }
1 голос
/ 22 октября 2011

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

0 голосов
/ 22 октября 2011

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

...