fork调用和递归

fork调用和递归
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{
    fork();
    fork();
    fork();

    puts("hi");

    return 0;
}

该程序打印 8 次“hi”并退出。为什么?是不是每个递归fork调用main都如:f(): "hi"; f()

答案1

不,fork不是传统意义上的“递归”递归。调用会fork()复制当前进程,因此它“返回两次”。对于子进程,返回值为0,对于父进程,返回值为子PID。 fork()不是重新启动main- 这更像是fork后面跟着exec.

你的程序是这样工作的。首先让我们插入一些行号:

 1: #include <stdio.h>
 2: #include <stdlib.h>
 3: #include <string.h>
 4:
 5: int main(int argc, char *argv[])
 6: {
 7:    fork();
 8:    fork();
 9:    fork();
10:
11:    puts("hi");
12:
13:    return 0;
14: }

假设你启动了你的程序,它的 PID 为

  • 第 7 行之后,调用fork会产生两个单独的进程,都在8号线, 1个带PID(原始)和一个 pid 为C1(新孩子)。

  • 运行第 8 行并生成一个带有 PID 的新子进程C2。两个都C2现在在9号线。同时,C1运行第 8 行并生成一个新的子进程,CC1。两个都CC1C1也在9号线。 (不完全相关,但上述两句话发生的顺序是不确定的。它们可能在多处理器系统上同时发生。)

现在共有4个进程:,C1,C2, 和CC1。正如您所看到的,每次连续的fork进程数量都会增加一倍。由于有 3 个fork调用,因此最终会得到 2、38 个进程。家谱看起来像这样:

P (initial process, started by you)
+-- C1 (created on line 7)
|   +-- CC1 (created on line 8)
|   |   +-- CCC1 (created on line 9)
|   +-- CC2 (created on line 9)
+-- C2 (created on line 8)
|   +-- CC3 (created on line 9)
+-- C3 (created on line 9)

每个进程都是由树中的父进程创建的。

答案2

                           main()
                             |
                             |
                      fork()  ------------------
                              |                 |
                     fork()   -------        -------
                              |     |        |      |
                   fork()   ----   ----     ---    ---
                            |  |   |   |    |  |   |  |

这是上面代码的进程树,这就是 fork() 的工作原理。以及为什么它的打印 8 意味着它总是 2 的 n 次方(其中 n 是调用次数,即 fork() 。

相关内容