【问题标题】:Understanding the fork() statement and its process tree理解 fork() 语句及其进程树
【发布时间】:2013-09-17 03:02:00
【问题描述】:

我试图弄清楚使用以下 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 个进程(包括主进程)。我做错了吗?

【问题讨论】:

    标签: c linux fork


    【解决方案1】:

    (1)fork之后的那一行。

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

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

    【讨论】:

    • 感谢您澄清这一点。我现在又有一个新的困惑,如果你有空闲时间,也许你也可以澄清一下。 if 语句中有一个 fork()。那么,如果孩子在下一行开始进程,它会忽略 if 语句块内的 fork() 吗?这是我必须假设的,因为在那个特定的子进程中,if 语句永远不会满足。
    • 您的 if 语句是 forkfork 会生一个孩子。在孩子中,fork 返回零,以便 if 语句将评估为 false 并且不会被孩子执行。然而,父母将在 if 语句中从 fork 接收孩子的 pid。 pid 永远不会为零,因此 if 语句将为父级计算为 true,并且他将执行 if 代码。
    • 再次感谢您的帮助!
    【解决方案2】:

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

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

    【讨论】:

    • 谢谢。这消除了我对它进入下一行代码的误解。当前语句实际上是由两个进程以当前值来判断的。那么,我的流程树看起来是否正确?我通过添加一些我错过的进程来更新它。此外,节点编号基于当前分叉发生的行。
    • @TheRationalist:它有正确数量的节点。不过,我觉得演示文稿有点混乱。
    【解决方案3】:

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

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

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

    答:是的。

    问:fork实际是父时是否返回父id的值,当是子时总是0

    答:是的。除非创建进程时出错,否则返回 -1。

    查看这里了解更多信息:

    【讨论】:

    • 只创建了1个新进程;子进程的 pid 返回给父进程而不是它自己的 pid。
    • Quib​​ble quibble quibble :(。重点是1)是的,当前进程“分裂”,2)最终结果是两个进程。
    • 实际上,Duck 明白我在问题中的意思。我的困惑不是是否产生了两个过程,而是调用 fork 的原始过程是否被认为是两个产生的过程之一。现在回想起来,我意识到我并没有像我应该说的那样清楚。不过感谢您的回复。
    猜你喜欢
    • 2023-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-07
    • 1970-01-01
    相关资源
    最近更新 更多