Я не понимаю этот пример fork()
У меня есть этот пример кода, но я не понимаю, почему этот код создает 5 процессов плюс оригинал. (Всего 6 процессов)
#include <unistd.h>
int main(void) {
int i;
for (i = 0; i < 3; i++) {
if (fork() && (i == 1)) {
break;
}
}
}
![Process graph]()
Ответы
Ответ 1
fork()
разбивает процесс на две части и возвращает либо 0 (если этот процесс является дочерним), либо PID дочернего элемента (если этот процесс является родительским). Итак, эта строка:
if (fork() && (i == 1)) break;
Говорит "если это родительский процесс, и это второй раз через цикл, вырваться из цикла". Это означает, что цикл работает следующим образом:
-
i == 0
: первый раз через цикл, i
равен 0, мы создаем два процесса, которые входят в цикл в i == 1
. Всего сейчас два процесса
-
i == 1
: оба этих процесса fork, но два из них не продолжают выполнять итерацию из-за строки if (fork() && (i == 1)) break;
(две из них не продолжаются, это оба родителя в вызовах fork), Всего четыре процесса,, но только два из них продолжают цикл.
-
i == 2
: Теперь два, которые продолжают цикл как fork, , приводящие к 6 процессам.
-
i == 3
: все 6 процессов выходят из цикла (поскольку i < 3 == false
, больше нет циклов)
Ответ 2
Если ваш основной процесс имеет pid A, а B - F - подпроцессы pids, то:
A spawns B i=0
A spawns C i=1
C run from 'fork' i=1
C spawns D i=2
B run from 'fork' i=0
B spawns E i=1
D run from 'fork' i=2
E run from 'fork' i=1
E spawns F i=2
F run from 'fork' i=2
Где i
- значение i
контекста процесса (под).
Поскольку fork
создает точную копию текущего процесса, переменная i
также будет скопирована. Когда A порождает B, i
равно 0. Когда A порождает C, i
равно 1. Процесс A теперь выходит из цикла for, поскольку я == 1.
Теперь подпроцесс C начинает запускаться с i
== 1. Обратите внимание, что он не будет ломаться внутри цикла for, поскольку fork(), в точке нереста C, возвращает 0. Вместо этого он будет зацикливаться, увеличивая i
до 2, порождать D и выйти из-за условия for-loop.
Подпроцесс B имеет i
== 0, когда он запускается. Он порождает подпроцесс E и разбивается внутри цикла for. (i == 1)
И так далее...
Когда вы пытаетесь найти такие вещи, я могу дать вам совет:
Сделайте промежуточные переменные и распечатайте их.
Я изменил ваш код, чтобы он распечатывал только что описанные мной вещи:
#include <unistd.h>
#include <stdio.h>
int main(void) {
int i;
for (i= 0; i < 3; ++i) {
int f = fork();
printf("%i\tspawns\t%i\ti=%i\n", getpid(), f, i);
if (f && (i == 1))
break;
}
getchar();
}
Ответ 3
В родительском процессе fork() возвращает PID дочернего процесса, а в дочернем процессе он возвращает 0. Учитывая это, посмотрите на каждую итерацию цикла for:
(Скажем, для простоты, что PID исходного процесса равен 1)
- я == 0
- Процесс 1: я == 0, fork возвращает PID дочернего процесса (скажем 2) (2!= 0), true && & false == false, поэтому мы не сломаемся.
- Процесс 2: я = 0, fork возвращает 0, false && false == false, поэтому мы не сломаемся.
- я == 1
- Процесс 1: я == 1, fork возвращает PID дочернего процесса (скажем 3), true && & true == true, поэтому перерыв.
- Процесс 2: я == 1, fork возвращает PID дочернего процесса (скажем 4), true && & true == true, поэтому перерыв.
- Процесс 3: я == 1, fork возвращает 0, false && & true == false, поэтому не прерывайте.
- Процесс 4: я == 1, fork возвращает 0, false && true == false, поэтому не прерывайте.
- я == 2
- Процесс 1 вышел из цикла.
- Процесс 2 вышел из цикла.
- Процесс 3: я == 2, fork возвращает PID дочернего процесса (скажем, 5), true && & false == false, поэтому не прерывайте
- Процесс 4: я == 2, fork возвращает PID дочернего процесса (скажем, 6), true && & false == false, поэтому не прерывайте
- Процесс 5: я == 2, fork возвращает 0, false && false == false, поэтому не прерывайте
- Процесс 6: я == 2, fork возвращает 0, false && false == false, поэтому не прерывайте
- я == 3 так сделано с помощью цикла.
Ответ 4
Здесь можно считать шесть процессов (X):
i=0 fork()
/ \
i=1 fork() fork()
/ \>0 / \>0
| X break | X break
i=2 fork() fork()
/ \ / \
X X X X
Ответ 5
цикл выполняется от i==0
до i==2
.
В первом итерации исходный процесс (p0) создает еще один (p1)
Во второй итерации p0
и p1
создайте один новый процесс каждый (p2 и p3) и break (Так как i==1
и fork
возвращают отцу ненулевое значение).
В третьем итерации p2
и p3
создайте каждый новый процесс (p4 и p5).
Итак, наконец, у вас появилось 5 новых процессов.
Ответ 6
Сначала у нас есть один процесс. Рассмотрим итерации цикла:
i = 0
Первый процесс вызывает fork. Теперь у нас есть 2 процесса.
i = 1
Два процесса вызывают fork. Теперь мы имеем 4.
Fork возвращает 0 во вновь созданных процессах: два процесса прерываются от цикла, а два будут продолжаться в цикле.
i = 2
Два оставшихся процесса вызывает fork. Мы получаем 2 новых процесса (всего 6).
Ответ 7
В процессах детей цикл продолжает повторяться. Поэтому они также производят новые процессы.