【问题标题】:How many processes are forked here这里分叉了多少进程
【发布时间】:2012-11-23 17:03:53
【问题描述】:

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

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

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

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

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

【问题讨论】:

    标签: c process fork


    【解决方案1】:

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

    编辑 重新措辞以回应评论。所有返回值的含义见fork(2) man page

    【讨论】:

    • @Wooble 好点。我将编辑我的答案以确保清楚。
    • @JohnW.O'Brien 有没有办法让分叉的进程从头开始执行......只是好奇。我知道这会导致无限循环。只是想我可以使用分叉而不是递归来解决一些问题;)
    • @sidharthsharma 您需要检查 fork() 的返回,并在发现您正在作为孩子执行时,实施一些控制流以返回开始。或者,您可以在分叉后自己执行(),这肯定从头开始,但不保留其他状态。 EDIT 没有 fork() 的 exec() 不是很有用。
    【解决方案2】:

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

    所有四个都命中了第三个 fork,所以你有八个进程。然后他们都退出了。

    【讨论】:

      【解决方案3】:

      很简单,总共有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下面的所有代码都适用于父进程和子进程。

      【讨论】:

      • 有没有办法让分叉的进程从头开始执行......只是好奇。我知道这会导致无限进程的创建
      • 从头开始意味着什么?无论如何,您需要一个进程来调用fork() 函数,然后创建一个新进程。请稍微清楚具体一点?
      • 一开始我是从 main() 本身暗示... @John W. O'Brain 解释说,分叉的进程继承了父进程的执行状态,因此它将从调用fork() 的点。我想知道它是否可以从main()开始执行...
      • 因为它复制了整个过程控制块PCB,包括程序计数器状态。因此执行从fork语句的正下方开始。所以,如果你愿意,那么你必须将程序计数器设置为您要开始的具体地址位置。
      【解决方案4】:

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

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

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

      【讨论】:

      • @sidharthsharma 因为你有三个无条件的fork()s,每个fork() 使进程数加倍(除非它失败)。 2³ = 8.
      猜你喜欢
      • 1970-01-01
      • 2019-10-17
      • 2020-07-04
      • 2013-11-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-22
      • 2013-10-07
      • 1970-01-01
      相关资源
      最近更新 更多