if else 语句与 fork() 并发

if else statement concurrency with fork()

在阅读一些关于 C 中 fork() 的文章时,我看到了这个我无法理解的示例(下面的代码):

理解问题: 我们只 运行 "if" 或 "else" 而不是两者。但是由于 child 和 parent “同时”处理 运行,在这个例子中我们看到我们同时经历了“if”和“else”! 尽管它是同时的,但实际上并非如此,这取决于哪个进程将首先获得 CPU(对吗?)。

让一切变得“怪异”的是我们可能会先通过“else”,然后通过“if”。这怎么可能?

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
void forkexample()
{
    // child process because return value zero
    if (fork() == 0)
        printf("Hello from Child!\n");
  
    // parent process because return value non-zero.
    else
        printf("Hello from Parent!\n");
}
int main()
{
    forkexample();
    return 0;
}

可能的输出是:

来自 Child 的问候!

来自 Parent 的问候!

(或)

来自 Parent 的问候!

来自 Child 的问候!

请记住,fork 函数实际上 returns 两次:一次使用子进程的 pid 发送给父进程,一次使用 0 发送给子进程。

那时你有两个独立的进程运行相同的代码并打印到同一个终端。由于您有两个进程,内核可以自由地以任何它认为合适的方式安排它们,这意味着任何一个进程的输出都可以以任何顺序出现。

fork 是一个系统调用,它执行以下操作(在抽象中,现代系统的实际实现可能有所不同):

  • 在内存中创建进程映像的副本并将其设置为具有自己的 PID 的进程
  • 在一张图片中(child)returns 0
  • 第二张图(parent)returns新进程的PID
  • 像往常一样安排两个图像的执行

因此,在 multi-core 系统上,parent 和 child 将独立执行,并且没有其他同步,彼此之间没有任何关系.

如果您观察这两个进程的输出,您会发现它们的输出可以是任何形状或形式 - 您可以从 parent 的输出中获得在 [=28 的输出之前的输出=]、继承它或与它交错——你最终会看到什么是不可预测的。