Хорошо, это займет некоторый анализ.Лучше подумать о каждом процессе по очереди:
0: c2=0;
1: c1=fork();
2: if (c1==0) c2=fork();
3: fork();
4: if(c2>0) fork();
5: whatever
, а затем создать таблицу следующим образом, которая последовательно проходит по каждому процессу:
Seq PID CurC1 CurC2 Line Fork? NewC1 NewC2 ChPID ChC1 ChC2 ChLine ChSeq
--- --- ----- ----- ---- ----- ----- ----- ----- ---- ---- ------ -----
0 0 ? ? 0 NA ? 0
1 0 ? 0 1 Y >0 1 0 0 2 6
2 0 >0 0 2 N
3 0 >0 0 3 Y 2 >0 0 4 10
4 0 >0 0 4 N
5 0 >0 0 5 NA
6 1 0 0 2 Y >0 3 0 0 3 12
7 1 0 >0 3 Y 4 0 >0 4 15
8 1 0 >0 4 Y 5 0 >0 5 17
9 1 0 >0 5 NA
10 2 >0 0 4 N
11 2 >0 0 5 NA
12 3 0 0 3 Y 6 0 0 4 18
13 3 0 0 4 N
14 3 0 0 5 NA
15 4 0 >0 4 Y 7 0 >0 5 20
16 4 0 >0 5 NA
17 5 0 >0 5 NA
18 6 0 0 4 N
19 6 0 >0 5 NA
20 7 0 >0 5 NA
В этой таблице столбцы:
Seq
, порядковый номер шага. PID
идентификатор процесса, выполняющего шаг. CurC1
иCurC2
, значения для c1/c2
перед шагом. Line
,.номер строки шага. Fork?
, независимо от того, происходит ли разветвление на этой линии. NewC1
и NewC2
, если значения c1/c2
изменены шагом. ChPID
, идентификатор процесса дочернего элемента, если предположить, что произошел разветвление. ChC1
и ChC2
, начальные значения c1/c2
дочернего элемента, предполагающего разветвлениепроизошло. ChLine
, следующая строка в дочернем элементе, предполагая, что произошел форк. ChSeq
, последовательность, в которой начинается дочерний процесс, при условии, что произошел форк.
Итак, из этого видно, что всего было создано восемь процессов (включая тот, который вы запускали вручную в начале).Это не совсем соответствует семерке, которую вы перечислили, поэтому давайте найдем недостающую.
Причина, по которой я уверен, что я прав, заключается в том, что я запускаю следующую программу (называемую xyzzy
) вфон:
#include <unistd.h>
int main(void) {
int c1, c2 = 0;
c1=fork();
if (c1==0) c2=fork();
fork();
if(c2>0) fork();
sleep (60);
return 0;
}
, а затем выполнение ps -f | grep xyzzy
до завершения любого из операторов sleep
приводит к:
pax 13266 13150 0 21:01 pts/0 00:00:00 ./xyzzy
pax 13267 13266 0 21:01 pts/0 00:00:00 ./xyzzy
pax 13268 13266 0 21:01 pts/0 00:00:00 ./xyzzy
pax 13269 13267 0 21:01 pts/0 00:00:00 ./xyzzy
pax 13270 13267 0 21:01 pts/0 00:00:00 ./xyzzy
pax 13271 13267 0 21:01 pts/0 00:00:00 ./xyzzy
pax 13272 13269 0 21:01 pts/0 00:00:00 ./xyzzy
pax 13273 13270 0 21:01 pts/0 00:00:00 ./xyzzy
Другими словами, наряду с отображениямииз вашего вопроса и PID в моей таблице:
13266 (parent) Parent 0
13267 --> c1 // fork #1 1
13269 --> c2 //fork #2 3
13272 --> fork() // fork #3 6
13270 --> fork() // fork #3 4
13273 ??? 7
13271 --> fork() // fork #4 5
13268 --> fork() // fork #3 2
Так что это PID 7 из моей таблицы.Следуя порядковым номерам обратно к началу, мы получим вилки на 1, 7, 15, 20
, что будет в вашем исходном вопросе:
Потомок от fork # 1 затем вызывает fork # 2.Родитель этого форка # 2 имеет c2> 0. Затем на форке # 3 вы получите двух процессов с c2> 0, а не один.Оба из них будут раскошелиться на вилке № 4.