Попробуйте нарисовать дерево процесса создания и изучить / запомнить следующие моменты:
P1.fork()
возвращает pid (который больше tan 0) текущему процессу и возвращает 0 в дочернем процессе.
P2.вам нужно знать, как оценивается выражение A() && B() || C()
;например, если A()
возвращает 0 (false)
, функция B
не будет оценена, потому что 0 && whatever
всегда 0
.
Теперь давайте пометим вызовы для удобства ссылок:
Main()
{
Fork() /*[1]*/;
Fork() /*[2]*/ && fork ()/*[3]*/ || fork ()/*[4]*/;
Fork ()/*[5]*/;
}
Я нарисую первый уровень создания процесса (и немного второго уровня):
[0]
/ / \ \
[1] [2] [3] [5]
/ | \
[2] [3] [5]
Вышеуказанное дерево означает, что процесс [0] (начальный процесс) выполнит fork()
функции с номерами 1, 2, 3 и 5. Почему process [0]
не запустил fork()[4]
?Потому что fork()[2] && fork[3]
уже оценивается как true, поэтому нет смысла оценивать fork()[4]
.
Примените аналогичную концепцию к процессу, разветвленному fork[1]
на втором уровне, чтобы понять, почему процесс fork[4]
не был вызван.
Вы можете дополнить дерево создания процесса, применив P1 и P2 на каждом уровне дерева создания процесса.