无法理解 fork() 输出

Trouble understanding fork() output

假设有一个 PID = 1 的进程,它运行以下代码:

int a = fork();
int b = fork();
printf(“a: %d, b: %d\n”, a, b); 

让我们进一步假设新的PID将被一个一个地给出,所以第二个给出的PID将是2,然后是3等等

可能的输出是:

a:2, b:3
a:2, b:0
a:0, b:4
a:0, b:0

我在尝试理解上述代码的输出时遇到了一些麻烦,尤其是为什么 a:0, b:4a:2, b:3

fork之后,你可以在父(fork returns child的PID)或者在child( fork returns 0).

在第一次调用 fork 之后,您将有 2 个进程:父亲(在您的示例中为 a = 2)和 child(a = 0)。

两者都会分叉,父亲(a = 2)会给出一个child(b = 0)和一个新的父亲(b = 3)。 child (a = 0) 将给出一个新的 child (b = 0),它将成为父亲 (b = 4).

您可能的输出是:

a:2, b:3 -> father and father
a:2, b:0 -> father and child
a:0, b:4 -> child and father
a:0, b:0 -> child and child

第一次分叉前:

PID 1 (father)
a = (not in scope yet)
b = (not in scope yet)

第一次分叉后:

PID 1 (father)
a = 2
b = (not in scope yet)

PID 2 (child of 1)
a = 0
b = (not in scope yet)

第二次分叉后:

PID 1 (father)
a = 2
b = 3

PID 2 (child of 1)
a = 0
b = 4

PID 3 (child of 1)
a = 2
b = 0

PID 4 (child of 2)
a = 0
b = 0

你知道的

The return value is the zero in the child and the process-id number of the child in the parent, or -1 upon error.

那么,让我们一步一步地看看这里发生了什么。

当调用 fork() 时,它会创建一个新的 child,id 为 n,然后在 child 0 中创建 returns并在 parent n.

所以让我们假设我们的进程为 pid 1,当第一个 fork() 被调用时,它创建一个 pid 2 的进程,然后 returns 为一个值. a 在进程 2(child)中将具有值 0,在进程 1(parent).

然后每个进程都会调用fork(),将return值赋给parent进程中的b。在 child 中,b 将具有值 0

无论如何,我认为这个模式会简化理解:

主要开始:

|
|
int a = fork(); // It creates a new process, and the old one continues going
|
|-------------------------|
a = 2; /* Parent */       a = 0; // Child
|                         |
|                         |
int b = fork();           int b = fork(); // Each one create a new process
|                         |
|                         |-----------------------------|
|                         /* Child -> Parent */         // Child -> Child
|                         a = 0; b = 4;                 a = 0; b = 0
|
|
|
|
|-----------------------------|
/* Parent -> Parent */        // Parent -> Child
a = 2; b = 3;                 a = 2, b = 0; 

我什至不想回答你的问题。它更多地是关于显示常用的模式。如果注释中有正确的代码格式,它可能是注释。

fork()的基本结构是:

if (int PID = fork() == 0 ) {
    //it's a child process
} else {
    //it's a parent process
}

使用简单

int PID1 = fork();
int PID2 = fork();

风险很大,因为您几乎肯定会收到 Race condition.

Original process:
forks child A, and child B
prints `a:2, b:3`

    child A process:
    forks child BB
    prints `a:0, b:4`

        child BB proess:
        forks nothing
        prints `a:0, b:0`

    child B process:
    forks nothing
    prints `a:2, b:0`

并且由于您没有使用任何 waitwaitpid,因此它们可以以任何顺序出现。