Я не понимаю эту диаграмму fork () - PullRequest
5 голосов
/ 14 февраля 2012

enter image description here

Как мы можем получить этот процесс с этим условием? Схема процесса?

    int main (int argc, char **argv) {
    int i;
    int pid;
       for (i= 0; i < 3; i++) {
            pid = fork();

            if (pid < 0) break;// with this condition i dont understand??

       }
           while (wait(NULL) != -1);

Ответы [ 4 ]

8 голосов
/ 14 февраля 2012

fork() разбивает процесс на две части и возвращает 0 (если этот процесс является дочерним), или PID дочернего (если этот процесс является родительским), или -1, есливилка не удалась.Итак, эта строка:

if (pid < 0) break;

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

Диаграмма немного сбивает с толку из-за того, как процессы (круги)соответствуют fork() вызовам в цикле.Три дочерних процесса основного процесса создаются, когда i равно 0, 1 и 2 соответственно (см. Схему внизу этого поста).

Поскольку цикл продолжается как в родительском, так и в родительском процессах.Был вызван дочерний процесс из точечного форка, вот как происходит форкс:

  • i == 0: вилка вызывается в исходном родительском объекте.Теперь есть два процесса (верхний и левый).
  • i == 1: fork вызывается в двух существующих процессах.Новые дочерние элементы - это самый левый дочерний элемент на втором слое снизу, а средний дочерний элемент на третьем слое снизу.Сейчас существует четыре процесса
  • i == 2: fork вызывается во всех существующих процессах.Новые дочерние элементы - это все оставшиеся узлы (нижний узел, два крайних правых узла во втором слое от боррома и самый правый узел в третьем слое снизу)
  • i == 3: все 8 процессов выходят изloop

Снова приведена схема с числами, указывающими, какое значение i было в цикле при создании процесса:

                 -1  <--- this is the  parent that starts the loop
              /   |  \
             0    1   2
           /  \   |
          1    2  2
          |
          2
3 голосов
/ 14 февраля 2012

Чтобы понять вашу диаграмму, вы должны полагаться на поведение fork : он разбивает процесс на две части, создавая другой процесс, идентичный первому (за исключением PID), в новой ячейке памяти.

Если вы вызовете его в цикле, вот что произойдет:

Когда i=0, первый процесс будет разделен, создав другой процесс, который начнет работать именно с этой точки (поэтому будет пропущенпервый цикл).Сосредоточившись на первом процессе, он продолжит цикл, генерируя другой процесс при i=1.Второй процесс, таким образом, начнется с i=1, поэтому будут пропущены первые два цикла.Первый процесс будет разделен в последний раз на i=2.Последняя созданная копия, однако, начнет работать с i=2, поэтому она выйдет из цикла и ничего не сгенерирует.

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

Вы можете продолжить эти рассуждения и понять остальную часть диаграммы.

Как отмечали другие, if (pid < 0) - этопросто проверка, чтобы увидеть, есть ли ошибки и не изменяет логику кода.

2 голосов
/ 14 февраля 2012

fork возвращает -1 в случае ошибки и 0 или в положительном случае, поэтому строка if (pid < 0) break; говорит: «если произошла ошибка, выйдите из цикла».

Предполагая, что нет ошибки, это что-то вроде:

В начале i=0, и у вас есть один процесс. давайте назовем это p0.

В строке fork();, p0 создает другой процесс. давайте назовем это p1.

В каждом из них у нас есть i++ (так что теперь i равно 1), и мы снова повторяем цикл.

p0 и p1 по отдельности имеют команду fork();, поэтому каждый из них создает другой процесс. давайте назовем новые процессы p2 и p3.

Теперь в каждом процессе у нас есть i++, который устанавливает i равным 2, и мы снова запускаем цикл.

Каждый из 4 процессов, которые у нас есть, запускает строку fork(); и создает новый процесс. так что теперь у нас есть также p4, p5, p6, p7.

Каждый процесс увеличивает его i до 3, а затем, поскольку условие цикла теперь ложно, цикл, наконец, заканчивается.

Теперь процесс 8 (отдельно) переходит на следующую строку.

(Фактически, каждая итерация удваивает число процессов, поэтому если вы измените 3, например, 15, у вас будет 2 ^ 15 процессов в конце.)

2 голосов
/ 14 февраля 2012

fork возвращает -1, если вызов fork не удался.он возвращает pid в родительском и 0 в дочернем.Состояние, на которое вы смотрите, на самом деле не имеет значения для функционирования кода;он просто говорит, что если есть ошибка с форком, выйдите из цикла.Если в вызове fork ошибки нет, будет построено дерево процессов на диаграмме.

Причина в том, что тот же цикл будет продолжаться в дочерних процессах.Таким образом, дети также продолжат разветвляться, основываясь на значении i во время вызова разветвления.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...