Как использовать Fork () для создания только 2 дочерних процессов?

Я начинаю изучать C и, изучая форк, жду функции, которые я получил неожиданный вывод. По крайней мере для меня

Есть ли способ создать только 2 дочерних процесса из родительского?

Вот мой код:

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

int main ()
{
    /* Create the pipe */
    int fd [2];
    pipe(fd);

    pid_t pid;
    pid_t pidb;


    pid = fork ();
    pidb = fork ();

    if (pid < 0)
    {
        printf ("Fork Failed\n");
        return -1;
    }
    else if (pid == 0)
    {
        //printf("I'm the child\n");
    }
    else 
    {
        //printf("I'm the parent\n");
    }

    printf("I'm pid %d\n",getpid());

    return 0;
}

И вот мой вывод:

I'm pid 6763
I'm pid 6765
I'm pid 6764
I'm pid 6766

Пожалуйста, не обращай внимания на часть трубы, я еще не зашел так далеко. Я просто пытаюсь создать только 2 дочерних процесса, поэтому я ожидаю, что 3 "I'm pid ..." выводит только 1 для родительского процесса, который я заставлю ждать, и 2 дочерних процесса, которые будут взаимодействовать через канал.

Дай мне знать, если увидишь, где моя ошибка.

 dmckee06 июн. 2012 г., 16:06
fork (2) очень простой и один из самых неправильно понятых вызовов в Unix API. Просто посмотрите на «Связанные» боковую панель. Есть ли конкретная причина, по которой вы хотите общаться между двумя детьми, а не между родителем и ребенком?
 mimoralea06 нояб. 2014 г., 17:49
@ TwilightSparkleTheGeekman fork states: ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ В случае успеха PID дочернего процесса возвращается в родительском, а 0 - в дочернем. В случае ошибки -1 возвращается в родительский процесс, дочерний процесс не создается и значение errno устанавливается соответствующим образом.
 user362924906 апр. 2016 г., 23:29
опубликованный код вызывает второйfork() от родителя и ребенка, после этого (при условии, что ни один из них не вызоветfork() терпит неудачу) будет 4 процесса. И.Е. parent, child1 от первого вызова fork (), затем parent, child1, child2, child1a от второго вызова fork ()
 TwilightSparkleTheGeek27 июн. 2014 г., 10:59
Для вызова fork (), почему вы проверяете pid == 0? Как я узнаю, кто из них родитель, а кто ребенок?

Ответы на вопрос(5)

Решение Вопроса
pid = fork (); #1
pidb = fork (); #2

что идентификатор родительского процесса равен 100, первая ветвь создает другой процесс 101. Теперь и 100, и 101 продолжают выполнение после # 1, поэтому они выполняют вторую вилку. pid 100 достигает # 2, создавая другой процесс 102. pid 101 достигает # 2, создавая другой процесс 103. Таким образом, мы получаем 4 процесса.

Что ты должен сделать, это что-то вроде этого.

if(fork()) # parent
    if(fork()) #parent
    else # child2
else #child1
 mimoralea06 нояб. 2014 г., 17:51
Because fork возвращает 0 на дочернем, а не на родительском. Родителю возвращается PID дочернего процесса, который вы только что создали, что более полезно.
 Mohsin09 сент. 2016 г., 16:52
@ tuxuday Можете ли вы привести пример? Я не могу понять, как написать код для этого
 TwilightSparkleTheGeek27 июн. 2014 г., 10:56
Я думал, что родитель был после утверждения else. Почему родитель в операторе if? Я запутался
 sj75506 июн. 2012 г., 08:41
Это определенно работает. Однако я бы рекомендовал вместо этого использовать оператор switch. Функция fork может вернуть -1, и мы можем обработать эту ошибку с регистром -1 внутри оператора switch.

дочерний процесс создается так, как вы ожидаете. Можно сказать, что дочерний процесс также выполняет оператор fork, но возвращает 0, а родитель возвращает pid. Весь код после оператора fork выполняется обоими, родительскийа такж ребенок

В вашем случае произошло то, что первый оператор fork создал дочерний процесс. Так что в настоящее время есть один родитель, P1, и один ребенок, C1.

Теперь и P1, и C1 встречают второй оператор fork. Родитель создает другого дочернего элемента (c2), как и следовало ожидать, но даже дочерний элемент c1 создает дочерний процесс (c3). Таким образом, в действительности у вас есть P1, C1, C2 и C3, поэтому вы получили 4 вывода оператора печати.

Хороший способ подумать об этом - использовать деревья, где каждый узел представляет процесс, а корневой узел является верхним родителем.

0) создание процесса не удалось, это говорит о том, что создание дочернего процесса было неудачным .. fork возвращает идентификатор процесса дочернего процесса, если getpid () используется из родительского процесса ..

разом, вы можете получить 2 копии исходного родительского процесса.

int main (void) {
    pid_t pid, pid2;
    int status;

    pid = fork();

    if (pid == 0) { //child process
        pid2 = fork();
        int status2;

        if (pid2 == 0) { //child of child process
            printf("friends!\n");
        }
        else {
            printf("my ");
            fflush(stdout);
            wait(&status2);
        }
    }
    else { //parent process
        printf("Hello ");
        fflush(stdout);
        wait(&status);
    }

    return 0;
}

Это печатает следующее:

Hello my friends!

и нет, вторfork() будет выполняться как родительским процессом, так и дочерним процессом, поэтому у вас есть четыре процесса.

если вы хотите создать 2 дочерних процесса, просто:

if (pid = fork()) {
    if (pid = fork()) {
        ;
    } 
} 

Вы можете создать n дочерних процессов следующим образом:

for (i = 0; i < n; ++i) {
    pid = fork();
    if (pid > 0) {   /* I am the parent, create more children */
        continue;
    } else if (pid == 0) { /* I am a child, get to work */
        break;
    } else {
        printf("fork error\n");
        exit(1);
    }
}

Ваш ответ на вопрос