1

我试图弄清楚使用以下 C 代码创建了多少进程:

int main ()
{
   fork();
   if (fork()) {
      fork();
   }
   fork();
   return 0;
}

有几件事我很困惑:

每次调用 fork() 时,子进程是从代码的开头开始,还是从当前 fork() 创建它的位置开始?例如,如果调用了第 3 行的第一个 fork,我会在第 4 行还是第 1 行启动子进程?我相信这是一个愚蠢的问题,b/c 如果每个孩子从头开始,它会创建一个无限循环,但我想对这个假设保持安全。

接下来,当调用 fork 时,当前进程是否拆分为两个新进程,一个是父进程,另一个是子进程,还是当前进程自动成为父进程,所以实际上只创建了一个额外的进程。

最后,使用 if 语句,我很确定 fork 在它实际上是父级时返回父级 id 的值,当它是子级时总是 0。那么,我是否正确假设 if 语句对于每个产生的孩子都是错误的?

有了以上所有假设,这是我提出的流程树,如果有人看到导致它失败的错误,我将不胜感激。树中子节点的数量代表当前分叉发生的代码行:

        main
  |    |    |    |
  3    4    5    7    // the main/initial process calls fork 4 times
| | |  |    |    
4 5 7  7    7         // the first fork will see 3 additional forks since it was called
| |                   // at line 3 and I assume resumes at line 4.
7 7                   // The second and third original children would each only callthe
                      // very last fork().  The last fork has no other forks following.

因此,总共创建了 10 个进程(包括主进程)。我做错了吗?

4

3 回答 3

1

(1) 紧跟在fork.

(2) 一种新工艺。孩子是父母的副本。

(3)在父进程中fork返回子进程的pid,在子进程中返回 0。对于每个孩子来说,if 语句都是错误的。它应该出现在 12 个进程中。我不擅长绘制图表,但你应该能够弄清楚。

于 2013-09-17T03:07:47.770 回答
1

在这里要清楚一点,这并不是说孩子从任何特定的行“开始”。(无论如何,行在运行时实际上并不存在。)

子节点在分叉点成为父节点的精确副本(其内核进程记录除外)。因此 fork() 被调用一次但返回两次,一次在父级中,一次在子级中。这就是为什么它被称为叉子。差异从返回的那一刻开始,因为 fork 的返回值在两个分支中是不同的。但在这两种情况下,它只是一个普通的函数返回。

于 2013-09-17T03:51:44.740 回答
0

问:每次调用 fork() 时,child 是从代码的开头开始,还是从当前 fork() 创建它的位置开始?

A:来自“fork()”之后的语句。

Q:调用fork时,当前进程是否会分裂(产生一个)NEW进程?

答:是的。

Q:fork实际是parent时是否返回parent id的值,是child时总是0

答:是的。除非创建进程时出错,在这种情况下它返回 -1。

在这里查看更多信息:

于 2013-09-17T03:15:52.283 回答