2012-02-13 3 views
5

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); 
+3

если это #homework, отметьте его как таковой –

+0

Функция называется «fork», а не «вилка»; Я исправил заголовок. –

ответ

8

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

if (pid < 0) break; 

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

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

Поскольку цикл продолжается был назван как родитель и дочерний процесс с точки развилки, это то, как вилы бывает:

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

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

    -1 <--- this is the parent that starts the loop 
      / | \ 
      0 1 2 
     /\ | 
      1 2 2 
      | 
      2 
2

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

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

3

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

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

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

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

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

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

2

fork return -1 on error и 0 или positive else, поэтому строка 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 процессов в конце.)