#include <stdio.h>
int main()
{
printf("Hello");
fflush(stdout);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
#include <stdio.h>
int main()
{
printf("Hello");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我试图了解 fflush(stdout) 的用法以及上面两个程序有什么区别?
在现代操作系统上运行的普通 C 程序中,文件访问会被缓冲两次(或者当您计算驱动器中的缓冲区等缓冲区时会缓冲更多次)。一个缓冲区在结构体中实现FILE,另一个在内核中实现。
通常,该FILE结构会缓冲程序内部缓冲区中的内容。当您向缓冲文件写入内容时,内容将保留在正在运行的程序内部的缓冲区中。当缓冲区已满时,以及当缓冲模式为行缓冲时,在行末尾将其写入操作系统。例如,该数据通过系统调用写入操作系统write()。缓冲区之所以存在,是因为系统调用需要从用户程序到内核的上下文切换,这是相对昂贵的(慢),缓冲区在这里是为了减少系统调用的数量。您还可以直接使用程序中的系统调用而不使用函数stdio,但是,此函数的可移植性较差且处理起来更复杂。Afflush(stdout)检查缓冲区中是否有任何应写入的数据,如果有,则使用底层系统调用将数据写入操作系统。
当系统调用返回时,数据就在您的内核中。但现代操作系统也会缓冲这些数据。这用于减少磁盘写入次数、减少延迟等。该缓冲区完全独立于FILE程序内的缓冲区。
请注意,这并不适用于所有系统。例如,微控制器环境可能提供一些stdio.h直接写入 UART 的功能,无需任何缓冲区,既不需要内部操作系统,FILE也不需要任何(可能不存在)操作系统。
要了解fflush()对正在运行的程序有何影响,请比较以下程序:
int main(void)
{
fputs("s",stdout);
fputs("e",stderr);
}
Run Code Online (Sandbox Code Playgroud)
和
int main(void)
{
fputs("s",stdout);
fflush(stdout);
fputs("e",stderr);
}
Run Code Online (Sandbox Code Playgroud)
在Linux上,stderr默认情况下不缓冲,因此fputs("e",stderr);将立即打印数据。另一方面,fputs("s",stdout);Linux 上默认是行缓冲的,因此不会立即打印数据。这会导致第一个程序输出es而不输出se,但第二个程序输出se。
您可以使用以下命令更改缓冲模式setvbuf()