2

我正在使用 重定向stdout一个进程freopen(),只要它只是一个进程,一切都很好。

但是,如果我这样做:

freopen("stdout.txt", "a+", stdout);
printf("Initial line.\n");

int i=0;
while(i<1000)
    {
        if(fork())
            wait(NULL);
        else
            printf("Line %d.\n", i);
        i++;
    }

第一个打印的行会一遍又一遍地重新打印在文件上。我应该做些什么来避免这种情况发生吗?

4

1 回答 1

0

第一个打印的行会一遍又一遍地重新打印在文件上。

这是因为标准 C 库在使用函数时将缓冲应用于标准输出流。stdio特别是,当stdout被重定向到文件时,缓冲模式从行缓冲变为完全缓冲(由库定义大小的缓冲区)。在行缓冲模式下,只有在遇到换行符时才会刷新缓冲区(以及实际写入的数据),在完全缓冲模式下,这只会在达到最大缓冲区大小时发生。

当您创建多个进程时,它们都共享父级的相同缓冲区。由于在生成新子代之前您没有到达缓冲区的末尾,并且您没有清空它,因此它们都将具有相同的缓冲区内容。之后,当每个孩子死亡时,标准库会自动刷新缓冲区。

我应该做些什么来避免这种情况发生吗?

是的。在创建孩子之前刷新缓冲区。

freopen("stdout.txt", "a+", stdout);
printf("Initial line.\n");
fflush(stdout);

// ...

您可能还想exit()在孩子完成工作后的下一个周期之前:

int i=0;
while(i<1000)
{
    if(fork()) {
        wait(NULL);
    } else {
        printf("Line %d.\n", i);
        exit(0);
    }

    i++;
}
于 2020-09-09T14:10:14.653 回答