【问题标题】:Process Creation Using Fork()使用 Fork() 创建进程
【发布时间】:2023-03-22 19:34:01
【问题描述】:

在运行以下代码时:

#include <stdio.h>
#include <unistd.h>
static int x = 0;
int main(int argc, char *argv[])
{
    pid_t p = getpid();
    fork();
    x++;

    if (! fork()) {
      x++;
      if (fork()) {
          x++;
      }
    }

    printf("p%d: x = %d\n", getpid() - p, x);
    sleep(60);
     return 0;
}

我得到以下输出:

p0: x = 1
p1: x = 1
p2: x = 3
p3: x = 3
p4: x = 2
p5: x = 2

我不太明白这些值是如何以及在何处增加的。 原始进程 (p0) 执行 main() 函数。第一个 fork() 创建一个 子进程 (p1)。然后,p0 和 p1 都将它们的 x 副本设置为 1。

接下来,两个进程在第二个分叉上创建另一个子进程(p2 和 p3)。两个新的子进程 p2 p3 增加 x 的副本,即 x 的副本变为 2。但是p0 和p1 呢?他们不增加值吗?

接下来是什么? p4 和 p5 的值如何递增?有人可以解释一下吗?

【问题讨论】:

    标签: c linux unix fork system-calls


    【解决方案1】:

    fork 返回以下之一:

    • -1 出错(并设置 errno)。
    • 0 在孩子中。
    • 父项中子项的 pid(真值)。

    假设fork 没有失败,这意味着!fork() 仅在子级中为真,fork() 仅在父级中为真。

                                           p0 p1 p2 p3 p4 p5
                                           -- -- -- -- -- --
    static int x = 0;                   x = 0
    
    // p1 created as a copy of p0.
    fork();                                 0  0
    
    x++;                                    1  1
    
    // p2 created as a copy of p0.
    // p3 created as a copy of p1.
    if (! fork()) {                         1  1  1  1
      // Only p2 and p3 reach here.
      x++;                                  1  1  2  2
    
      // p4 created as a copy of p2.
      // p5 created as a copy of p3
      if (fork()) {                         1  1  2  2  2  2
          // Only p2 and p3 reach here.
          x++;                              1  1  3  3  2  2
      }
    }
    

    【讨论】:

    • 如果您使用与 OP (p0...p5) 相同的编号方案,此答案会更有帮助
    • @x89 这不仅仅是一个好的答案。它展示了一种技术,一种思考/推理问题的方式,可以在未来帮助你。当我看到你的问题时,这基本上是我所做的(在纸上),但 ikegami 在这里提供了更好的视觉表示。
    【解决方案2】:

    我认为您误解的关键在于 fork 系统调用的返回值。 调用 fork 时,它为新创建的进程(又名子进程)和旧进程(又名父进程)返回不同的值。

    在子进程中,fork返回0。

    在父进程中,fork返回子进程的PID。

    例如写if (fork())时,父进程会进入if子句,而子进程不会。反之亦然——写if (!fork())时,子进程会进入if子句,而父进程不会。

    【讨论】:

      猜你喜欢
      • 2021-07-09
      • 1970-01-01
      • 2014-07-20
      • 2012-03-31
      • 2021-12-15
      • 1970-01-01
      • 2014-07-27
      • 2021-06-11
      • 1970-01-01
      相关资源
      最近更新 更多