为什么 "Line buffer stdout to ensure lines are written atomically and immediately"

why "Line buffer stdout to ensure lines are written atomically and immediately"

我正在阅读 wc 命令的源代码,在 main 函数中我发现了以下代码:

  /* Line buffer stdout to ensure lines are written atomically and immediately
     so that processes running in parallel do not intersperse their output.  */
  setvbuf (stdout, NULL, _IOLBF, 0);

那么为什么行缓冲区标准输出要确保?

假设块缓冲用于标准输出而不是行缓冲。 (例如,如果 stdout 指的是常规文件,这是默认值。)让缓冲区大小为 1024 字节(以便输出每 1024 字节刷新到文件中),并假装两个进程正在写入同一个文件。

假设第一个进程当前在其 I/O 缓冲区中有 1020 个字节,并将行 "foo_file 37\n" 写入标准输出。这会将 "foo_" 放在 I/O 缓冲区的末尾,将缓冲区刷新到文件(因为缓冲区现在已满),然后将 "file 37\n" 放在缓冲区的开头。假设第二个进程随后出现并刷新其缓冲区,该缓冲区恰好以 "bar_file 48\n" 开始。输出文件中的结果行将是 "foo_bar_file 48",这显然不是我们想要的。

基本问题是当使用块缓冲时,缓冲区边界不一定对应于行边界。

您可以尝试将以下程序的两个实例写入同一个文件,以亲自查看此效果:

#include <stdio.h>

int main(void) {
    setvbuf (stdout, NULL, _IOLBF, 0);
    for (;;)
        puts("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");
    return 0;
}

注释掉 setvbuf() 调用后,您会看到一些行与其他行混淆了。请注意,这个 will 程序当然会很快写入一个巨大的文件。 :)