我正在阅读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要确保这一点呢?

最佳答案

say块缓冲用于stdout而不是行缓冲。(例如,如果stdout引用常规文件,则这是默认值。)将缓冲区大小设为1024字节(以便每隔1024字节将输出刷新到文件),并假设两个进程正在写入同一文件。
假设第一个进程的I/O缓冲区中当前有1020字节,并将"foo_file 37\n"行写入stdout。这会将"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()调用被注释掉时,您将看到一些行与其他行混淆。当然,要注意这个程序会很快写一个大文件。:)

关于c - 为什么“行缓冲区标准输出以确保自动原子地写行”,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29609816/

10-08 22:40
查看更多