C Процессы fork () - PullRequest
       15

C Процессы fork ()

3 голосов
/ 15 февраля 2011

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

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

int main(int argv, char *argc[])
{
    int i;
    pid_t childpid;

    for(i=0; i<3; i++)
    {
        childpid = fork();
        if(childpid == -1)
        {
            perror("Failed to Fork");
            return 1;
        }

        if(childpid == 0)
            printf("You are in Child: %ld\n", (long)getpid());
        else
            printf("You are in Parent: %ld\n", (long)getpid());
    }
    return 0;
}

OUTPUT:
You are in Parent: 30410
You are in Child: 30411
You are in Parent: 30410
You are in Child: 30412
You are in Parent: 30411
You are in Parent: 30410
You are in Child: 30413
You are in Child: 30414
You are in Parent: 30412
You are in Parent: 30411
You are in Child: 30415
You are in Child: 30416
You are in Parent: 30413
You are in Child: 30417

Я понимаю, что в ситуации fork() родитель или ребенок могут получить предпочтение в исполнении.Меня не беспокоит, меня беспокоит количество выполняемых процессов.Почему это 14?а не какое-то число 2 ^ n, что случится, если мы будем выполнять fork(); fork(); fork(), то есть разветвления один за другим.

Что мне не хватает?

ОБНОВЛЕНИЕ: Еще одно уточнение -

Функция fork копирует образ родительской памяти, так что новый процесс получает копию адресного пространства родителя.

Чтоэто значит?Означает ли это -

  1. дочерний процесс начинает выполняться после оператора fork()?
  2. дочерний процесс получает копию переменных родительского процесса?так что если x=3 над вилкой, дочерний процесс увидит этот x как 3?

Ответы [ 5 ]

12 голосов
/ 15 февраля 2011

У вас есть 8 выполняемых процессов, просто некоторые из них печатаются более одного раза из-за цикла.

Если вы сортируете вывод:

You are in Parent: 30410
You are in Parent: 30410
You are in Parent: 30410

You are in Parent: 30411
You are in Parent: 30411
You are in Child: 30411

You are in Parent: 30412
You are in Child: 30412

You are in Parent: 30413
You are in Child: 30413

You are in Child: 30414

You are in Child: 30415

You are in Child: 30416

You are in Child: 30417

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

Причина этого неуловима.Поскольку дочерний процесс наследует (почти) все от родительского, он также получает текущее состояние цикла.Я говорю «почти», поскольку некоторые вещи разные, такие как PID (очевидно), PID родительского (одинаково очевидно) и определенные ограничения ресурсов (в зависимости от ОС).

Итак, процесс 0, когда i == 0раздваивается на две части.оба с их следующим циклом в i == 1.Оба они разветвляются со своим следующим циклом на i == 2.И так далее.

Если вы изучите следующую диаграмму, вы сможете увидеть процесс создания.

      ____A____
     /    |    \
    B_    C_    D
    | \     \
    E  F     G
     \
      H

Линии /, | и \ представляют собой вилки в точках, где i равно 0, 1 и 2 соответственно.

Обратите внимание, что процесс (такой как E), который был создан из родительского элемента, где i == 1 будет работать только с i == 2.Другими словами, он был создан с помощью |, поэтому его следующим шагом будет \.

Аналогично, B, который был создан с помощью / (i == 0), будет только разветвляться с | (i == 1) и \ (i == 2).

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

2 голосов
/ 15 февраля 2011

Когда вы вызываете fork (), программа запускается именно там, где она была во время обработки.Итак, у вас есть

i = 0, 2 процесса
i = 1,4 процесса
i = 2, 8 процессов

как rlibby , указанных вВ своем комментарии я забыл принять во внимание тот факт, что процессы из каждого исходного прохода являются частью итогов.Так что моя математика была неправильной.Должно быть:

i = 0, 1 процесс + 1 новый (всего 2)
i = 1, 2 процесса + 2 новых (всего 4)
i = 2, 4 процесса + 4новый (всего 8)

1 голос
/ 15 февраля 2011

Всего 8 процессов.Подсчитайте уникальные идентификаторы процессов.

1 голос
/ 15 февраля 2011

Я думаю, причина того, что вы создаете так много процессов, заключается в том, что когда вы fork дочерний процесс, он находится в середине цикла for. Следовательно, после того, как он распечатает, что это дочерний элемент, он продолжит цикл и разветвляет своих собственных дочерних элементов.

Чтобы это исправить, просто сделайте выход детей после печати, что они дети:

if(childpid == 0) {
    printf("You are in Child: %ld\n", (long)getpid());
    exit(0);
}

Кстати, это объясняет, почему вы видите 2 n процессов для цикла, выполняющего n итераций. На каждой итерации каждый процесс разбивается на два процесса, которые затем выполняются до конца итераций цикла. Это означает, что каждая итерация удваивает число процессов, поэтому после n итераций вы увидите 2 n процессов.

Надеюсь, это поможет!

0 голосов
/ 27 апреля 2014

Я думаю, что добавление разрыва вместо добавления выхода (0) также будет работать.

...