此程序创建了多少个进程,以及它们由哪些进程创建?

时间:2013-11-22 21:17:22

标签: c process parent-child

我正在跟踪此程序并确定创建了多少进程(假设没有发生错误)。我画了一个图表来可视化过程。在我的图表中,第一个fork()创建的第一个流程包含1,并且每个相应的父级都有指向每个子流程的箭头。这看起来是否正确?

代码:

 1: child2 = 0;
 2: child1 = fork();     // fork 1
 3: if (child1 == 0)
 4: {
 5:     child2 = fork(); // fork 2
 6: }
 7: fork();              // fork 3
 8: if (child2 > 0)
 9: {
10:     fork();          // fork 4
11: }

图表:

                 0
                /|\
               / | \
              1  3  4
             / \  \
            /   \  \
           2     3  4
          /     /
         /     /  
        3     4
       /
      /
     4

原理

  • 第2行的第一个fork()命令创建了子1
  • 第5行的第二个fork()命令仅为2创建了子1,因为if(child1 == 0),即fork()返回的唯一进程0到child11
  • 第7行的第3个fork()命令为301创建了子2,因为该语句是由每个进程执行的。
  • 第10行的第4个fork()命令为除4以外的每个进程创建了子2,因为每个进程都有一个child2的副本,该副本从fork()2除外,其中child2为0。
你怎么看?我是否解释了这段代码并正确绘制了图表?

更新

正确的图表是:

                 0
                / \
               /   \ 
              1     3
             /|\ 
            / | \  
           2  4  3  
          /       \
         /         \
        3           4

2 个答案:

答案 0 :(得分:3)

应用于您的示例的pstree命令显示:

       bash-+-a.out-+-a.out-+-a.out---a.out
                    |       |-a.out---a.out
                    |       `-a.out
                    `-a.out

如下所示,每行只有一个进程。

       bash-+-a.out-+---------------------
                    +-a.out-+-------------
                    |       +-a.out-------
                    |       |      `-a.out
                    |       |-a.out-------
                    |       |      `-a.out
                    |       `-a.out-------
                    `-a.out---------------

,在分支重新排序后,匹配@Macattack的回答。

请注意,您没有关于上图中过程创建的相对时间的信息;它只是最终结果。

要理解图表,让我们看一下父进程分叉后的树:

int main(void) {
    int child1 = fork();
}

结果是:

  bash-+-a.out---a.out
         ^ parent   ^child
然后,如果孩子再次分叉,

int main(void) {
    int child2 = 0;
    int child1 = fork();
    if (child1 == 0)
        child2 = fork();
}

我们得到:

  bash-+-a.out---a.out---a.out
         ^ parent   ^child  ^grandchild

但是,如果父母再次吵架孩子没有,

int main(void) {
    int child2 = 0;
    int child1 = fork();
    if (child1 > 0)
        child2 = fork(); 
 }

我们得到:

  bash-+-a.out-+-a.out  <- child1
           ^   `-a.out  <- child2
           parent

注意pstree通过合并相同的兄弟姐妹来压缩输出;您需要使用-c选项来阻止它,并查看完整的树。

答案 1 :(得分:1)

以下是我的解释,你可以决定它是否与你的匹配,我不会像30和{{1}那样说“创建的孩子1” “因为每个人都是一个独立的孩子。

我的代码副本:

2

图表:(家长左,孩子右)

int main(void) {
    int child2 = 0;
    int child1 = fork(); // fork 1
    if (child1 == 0)
    {
        child2 = fork(); // fork 2
    }
    fork();              // fork 3
    if (child2 > 0)
    {
        fork();          // fork 4
    }
    printf("%jd\n", getpid());
}