-2

我知道这可能是一个愚蠢的问题,但任何人都可以帮助我理解以下代码片段的行为

//label 0
int main(){
  fork();//label 1
  fork();//label 2
  fork();//label 3
  return 0;
}

据我了解,流程树是这样的

              [0]
          /    |    \
        [1]   [2]   [3]
       /  \    |
      [2] [3] [3]
       |
      [3]

我对吗?如果是这样,我很困惑为什么第二个叉子没有产生与标签 1 叉子相对应的进程,而第三个叉子没有进一步产生任何进程。我的意思是子进程是父进程的精确副本(至少在代码中),因此它必须完整地执行其父进程的代码。谁能帮我解决这个困惑...

4

4 回答 4

4

是的,孩子是其父母的副本。它也继承了执行状态,包括父代码在哪里执行。当父节点从第一个 fork() 中返回子节点的 PID (>0) 时,它的第一个子节点返回 0,然后继续到第二个和第三个 fork。孩子不会回到 main() 的顶部,它只是从创建它的 fork 之后继续。

编辑回复评论。有关所有返回值的含义,请参见fork(2) 手册页。

于 2012-12-05T19:10:50.410 回答
3

在第一次分叉之后,您有两个进程。两者都击中了第二个分叉,总共创建了四个进程。

所有四个都命中了第三个分叉,因此您有八个进程。然后他们都退出。

于 2012-12-05T19:06:17.610 回答
1

很简单,总共有8个进程并行。

p ----------------
|                 |          // first fork() 
1c-------         p -------   
|        |        |        |      // second fork()
2c---    1c---    3c---    p----  
|   |    |    |   |    |   |    |    // third fork()
4c  2c   1c   5c  6c  3c   7c   p  

您可以计算8总共 8 个进程的叶节点。

解释:父p称为fork()2 进程1c第一个子进程和父进程。p现在第二个fork()进程用于两个进程。所以过程1c, 2c, 3c, p. fork()依此类推,第三次调用后您将获得 8 个进程。在 fork 之后,新进程在它被 fork 的代码之后执行。所以fork下面的所有代码都适用于父进程和子进程。

于 2012-12-05T19:17:58.883 回答
0

进程树如下所示。我对进程使用了​​以下命名约定。为创建它的相应分叉标签添加父进程名称的前缀。

                [0]
          /      |      \
        [01]    [02]    [03]
       /  \       |
    [012] [013] [023]
     /
   [0123]

就像@Mat 所说,创建了 8 个进程。

于 2012-12-05T19:19:05.563 回答