为什么 fork() return 这个组合中所有可能的输出?

why does fork() return all possible outputs in this combination?

问题:

我需要 clarification/help 了解 fork() 输出。我知道如何使用 fork() 在 c 中编写更详细和更大的代码,并使用其他概念,如管道、ipc、线程 (posix)。但是我对预测 return 输出的理解很糟糕,这就是为什么我要弄清楚这一点的原因我相信我的案例 1 是正确的,但我的其他案例模棱两可或与此相似,因为我对输出不太了解fork().

我对程序输出的了解还不错,我了解包含 for-loop、while-loop、if/else、数据结构、递归输出的基本算法。

但是,我缺乏关于使用 fork() 的程序如何准确输出以及 parent/child 过程组合如何完全如下所述的知识

我的方法:

最初我们有一个 parent 进程 运行 p0 然后 pid 派生了一个 child 进程。

因此,所有可能的输出将始终包含 0,因为最初 num=0 并且在第一个 prinf() 语句之前 num 未设置为任何其他数字。

我相信 parent 和 child 流程执行的时间是随机的,因为它可以以任何顺序出现。

情况 1:p0 打印 02,因为可能存在 pid 是 parent 的情况。然后分叉的 child 进程 p1 打印 01。最终答案将是 0201

情况 2:p0 打印 01 因为可能存在 pid 是 child 的情况(它是来自内核的主进程的 child 吗?)。然后分叉的 child p1 是一个 parent 所以它打印 0102。最终答案是 0102

情况 3:p0 打印 00,因为 pid 不是 child 或 parent。然后分叉的 child p1 打印 12 因为它同时是一个 child 和一个 parent 。最终答案是 0012.

情况 4:p0 打印 00,因为它不是 parent 或 child。然后分叉的 child 进程 p1 打印 21 因为它可以同时是 parent 和 child。 最终答案是 0021.

代码:

#include <stdio.h>
int num = 0 ;
int main(int argc, char *argv[])
{
  int pid ;
  pid = fork() ;

  printf("%d",num) ;

  if (pid == 0) {
    num = 1;
  } else if (pid > 0) {
    num = 2 ;
  }
  printf("%d",num) ;
}

答案:0102 或 0012 或 0201 或 0021

我猜你想得太复杂了。 fork() 之后发生的事情是您有两个实例(父子)正在执行,每个实例都执行两个输出操作。

这两个实例是独立的,彼此之间一无所知,因此一个不会等待另一个完成,这就是所谓的竞争条件。唯一的保证是每个进程将首先输出 0,然后是 1(或 2),因为这是每个进程中的操作顺序。但是你不能说这四个输出操作将如何交错。

我们称父进程为 A,子进程为 B。A 总是打印 0,然后是 2。 B 总是会打印 0 后跟 1。 A 相对于 B 的时间未定义。 A 的输出可以在 B 的输出之前、交错或之后打印。

实际上有六种可能的结果,如下所示。但是,您只会看到四种不同的输出模式,因为当输出以 00.

开头时,您无法判断是先打印 A 还是先打印 B
AABB
0201

ABAB
0021

BAAB
0021

ABBA
0012

BABA
0012

BBAA
0102