fork()如何使用像stdout这样的缓冲流?

时间:2013-09-07 08:44:53

标签: c linux

请查看以下代码。

#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)前一个..在哪里?                    即根据我的解释,输出应该是

                ...,.,.,.,

2 个答案:

答案 0 :(得分:5)

由于没有同花顺,所以不会写任何东西。每个fork ed进程都会在第二个printf之后准备好“。,”。

    fork();

我们有两个流程。

    printf(".");

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

    fork();

我们有四个流程。

    printf(",");

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

    return 0;

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

答案 1 :(得分:4)

没有刷新,每个进程(2个分叉后总共4个)将缓冲它的输出,并在进程退出时打印它(由库安装的退出处理程序),因为这里的所有输出都适合缓冲区而你不会触发冲他们。因此,每个进程将打印.,作为对内核的一次写入。进程之间没有同步(例如在退出之前等待子进程的父进程),所以顺序是未定义的,直到内核进程调度程序的奇思妙想,但由于输出每个进程是相同的,所以输出的内容无关紧要:

.,.,.,.,

所以关键在于,使用问题代码,没有刷新,写入发生在2个字符的块中,不可能交错各个字符。但这当然取决于控制台实现,并且一个可以编写一个控制台驱动程序,它一次只能处理一个字符,然后可能会发生各个字符的交错。我这样说是为了澄清,你所看到的并不是一些标准定义明确的行为,而是由于实现细节而导致事情发生的原因。