我在《Unix环境高级编程》中读到过这样的内容:
行缓冲有两个注意事项。首先,标准 I/O 库用于收集每行的缓冲区大小是固定的,因此如果我们在写入换行符之前填充此缓冲区,则可能会发生 I/O。其次,每当通过标准 I/O 库从 (a) 无缓冲流或 (b) 行缓冲流(需要从内核请求数据)请求输入时,所有行缓冲输出流都会被刷新。 (b) 上限定符的原因是请求的数据可能已经在缓冲区中,这不需要从内核读取数据。显然,任何来自无缓冲流的输入(项目 (a))都需要从内核获取数据。
https://www.gnu.org/software/libc/manual/html_node/Flushing-Buffers.html指出:
刷新缓冲流上的输出意味着将所有累积的字符传输到文件。在许多情况下,流上的缓冲输出会自动刷新:
当您尝试进行输出并且输出缓冲区已满时。
当流关闭时。请参阅关闭流。
当程序通过调用 exit 终止时。请参阅正常终止。当写入换行符时(如果流是行缓冲的)。
每当任何流上的输入操作实际上从其文件读取数据时。
所以我编写了一个程序来测试这个:
#include <stdio.h>
#include <unistd.h>
int
main()
{
printf("Hello");
FILE *fp = fopen("hugefile", "r");
if (fp == NULL) {
fprintf(stderr, "Cannot open file\n");
return -1;
}
setvbuf(fp, NULL, _IONBF, 0);
sleep(2);
char buf[10];
while (fread(buf, sizeof(char), 10, fp) == 10) {
}
if (ferror(fp)) {
fprintf(stderr, "Read error\n");
return -1;
}; // I expect "Hello" to appear on a screen but it doesn't
fclose(fp);
sleep(50);
}
但 fread() 不会触发输出闪烁。我是不是漏掉了什么?
我不知道这里可能与什么相关但我使用:
gcc 版本 14.2.1 20240910
glibc 2.40+r16+gaa533d58ff-2