请查看以下代码。
#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)前一个..
在哪里?
即根据我的解释,输出应该是
...,.,.,.,
答案 0 :(得分:5)
由于没有同花顺,所以不会写任何东西。每个fork
ed进程都会在第二个printf
之后准备好“。,”。
fork();
我们有两个流程。
printf(".");
他们每个人都准备写“。”。
fork();
我们有四个流程。
printf(",");
现在他们每个人都准备写“。,”。
return 0;
当每个进程刷新时,它会将“。”写入stdout
,产生最可能的输出“。,。,。,。,”。
答案 1 :(得分:4)
没有刷新,每个进程(2个分叉后总共4个)将缓冲它的输出,并在进程退出时打印它(由库安装的退出处理程序),因为这里的所有输出都适合缓冲区而你不会触发冲他们。因此,每个进程将打印.,
作为对内核的一次写入。进程之间没有同步(例如在退出之前等待子进程的父进程),所以顺序是未定义的,直到内核进程调度程序的奇思妙想,但由于输出每个进程是相同的,所以输出的内容无关紧要:
.,.,.,.,
所以关键在于,使用问题代码,没有刷新,写入发生在2个字符的块中,不可能交错各个字符。但这当然取决于控制台实现,并且一个可以编写一个控制台驱动程序,它一次只能处理一个字符,然后可能会发生各个字符的交错。我这样说是为了澄清,你所看到的并不是一些标准定义明确的行为,而是由于实现细节而导致事情发生的原因。