fork()如何处理像stdout这样的缓冲stream?

请看下面的代码。

#include <stdio.h> #include <sys/types.h> #include <unistd.h> int main(void) { fork(); printf("."); fflush(stdout); fork(); printf(","); return 0; } 

输出是:

 ..,,,, 

这对我来说是好的,

但如果我从上面的程序中删除fflush(stdout) ,那么输出应该是(根据我的理解)。

  ...,.,.,., 

fork()的语句是: fork()之后的语句被复制到父类和子类中。

我的理解是:在第一个fork()之后有两个进程(假设它是进程p和进程c)

进程p和c中的代码是:

  printf("."); fork(); printf(","); 

现在,假设进程p和c的第一个语句被执行,所以输出将是。

  .. 

现在fork()语句来执行。 所以,执行fork() ,我们的进程就像p,pc,c,cc​​。

每个p,pc,c和cc中的代码都是

  printf(","); 

我们不刷新stdout因此printf(".")仍然存在于每个缓冲区中。

所以每个进程都会打印.,所以输出结果是

  .,.,.,., 

我的问题是:1)以前哪里? 即根据我的解释输出应该是

  ...,.,.,., 

由于没有冲水,没有什么会被写入。 每个forked进程都将有“。”准备在第二个printf之后写入。

  fork(); 

我们有两个过程。

  printf("."); 

他们每个人都准备写“。”。

  fork(); 

我们有四个进程。

  printf(","); 

他们每个人现在都准备写“。”。

  return 0; 

当每个进程刷新时,它将“。”写入stdout ,产生最可能的输出“。,。,。,”。

如果没有刷新,每个进程(总共4个2叉)会缓冲它的输出,并在进程退出时打印它(由库安装的退出处理程序,我认为),因为这里的所有输出都适合缓冲区,并且不会触发刷新它们。 所以每个进程都会打印出来.,就像写入内核一样。 你在进程之间没有同步(比如在退出之前等待子进程退出的父进程),所以进程是未定义的,直到内核进程调度器的意愿,但是由于每个进程的输出是一样的,所以输出是无关紧要的:

 .,.,.,., 

所以这里最关键的是,在问题代码中,没有冲突,写入发生在2个字符的块中,不可能交织个别字符。 但是这当然取决于控制台的实现,而且可以编写一个控制台驱动程序,它一次只能处理一个字符,然后可能会发生各个字符的交错。 我只是想说明一下,你所看到的并不是一些标准的明确定义的行为,而是因为实现细节而发生的事情。