我正在阅读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);
那么为什么行缓冲区标准输出确保了?
答案 0 :(得分:3)
假设块缓冲用于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()
调用注释掉后,您会看到一些行与其他行混淆。请注意,这将使程序快速写入一个巨大的文件,当然。 :)