执行后fork()结果

时间:2011-10-17 12:51:17

标签: fork

我只需要问以下代码我的想法是否正确:

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

这是正确的吗?

1 个答案:

答案 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。
  • CurC1CurC2,该步骤前c1/c2的值。
  • Line,。步骤的行号。
  • Fork?,是否在该行发生了分叉。
  • NewC1NewC2,如果步骤更改了c1/c2值。
  • ChPID,孩子的进程ID,假设发生了分叉。
  • 假设发生了分叉,
  • ChC1ChC2是孩子的初始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处分叉。