我只需要问以下代码我的想法是否正确:
c2=0;
c1=fork(); // fork #1
if (c1==0)
c2=fork(); // fork #2
fork(); // fork #3
if(c2>0)
fork(); // fork #4
这是我的想法:
父进程将创建以下子进程:
家长 - > c1 // fork#1
- > fork()// fork#3
c1
- > c2 // fork#2
- > fork()// fork#3
- > fork()// fork#4
c2
- > fork()// fork#3
这是正确的吗?
答案 0 :(得分:3)
好的,这将需要一些分析。最好依次考虑每个过程:
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
执行步骤的“进程”ID。CurC1
和CurC2
,该步骤前c1/c2
的值。Line
,。步骤的行号。Fork?
,是否在该行发生了分叉。NewC1
和NewC2
,如果步骤更改了c1/c2
值。ChPID
,孩子的进程ID,假设发生了分叉。ChC1
和ChC2
是孩子的初始c1/c2
值。ChLine
,孩子的下一行,假设叉子发生了。ChSeq
,孩子开始的顺序,假设叉子发生了。因此,从中我们可以看到,共创建了 8个进程(包括您在开始时手动运行的进程)。这并没有完全证明你列出的七个,所以让我们找到失踪者。
我确信自己是正确的原因是因为在后台运行以下程序(名为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&gt;然后,在第3个分支处,您最终得到了具有c2&gt;的两个进程。 0,不是一个。这两个都将在fork#4处分叉。