为什么fork()会返回此组合中的所有可能输出?

时间:2015-02-21 09:58:27

标签: c output fork child-process

问题:

我需要澄清/帮助我理解fork()输出。我知道如何使用fork()在c中编写更详细和更大的代码,并使用其他概念,如pipe,ipc,threads(posix)。但是我对预测返回输出的理解是不好的,这就是为什么我想弄明白我相信我的情况1是正确的但我的其他情况是模棱两可或类似的因为我对fork()的输出不太稳固

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

然而,我对如何使用fork()完全输出的程序以及父/子进程组合完全如下所述缺乏了解。

我的方法:

最初我们有一个运行p0的父进程,然后pid分叉子进程。

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

我认为父子进程执行的时间是随机的,因为它可以按任何顺序出现。

案例1:p0打印02因为可能存在pid是父级的情况。然后分叉的子进程p1打印01.最终的答案是0201

案例2:p0打印01,因为可能存在pid是子节点的情况(它是来自内核的主进程的子节点吗?)。然后分叉的孩子p1是父母,所以它打印0102.最终的答案是0102

案例3:p0打印00,因为pid不是孩子或父母。然后分叉子p1打印12,因为它同时是一个孩子和一个父母。最后的答案是0012。

案例4:p0打印00,因为它不是父母或孩子。然后,分叉子进程p1打印21,因为它可以同时是父对象和子对象。 最终答案是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

2 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分:0)

让我们调用父进程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