为什么write()在输出重定向中的printf()之前打印?

Str*_*rry 5 c

所以我知道printf()write()使用更高级别并且最终使用write().Printf()缓冲并write()进行系统调用.

例1,如果我在printf()之前运行程序,write()那么它将输出值printf()之前的值write().

例2,如果我要运行相同的程序并让它通过输出重定向到一个文件,write()输出的值之前printf().

#include <stdio.h>
#include <unistd.h>

int main()
{
    printf("This is a printf test\n");
    write(STDOUT_FILENO, "This is a write test\n", 21);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我不明白这里发生了什么.在示例1中,程序是否printf()在运行之前等待s输出write()?在示例2中,程序是否重定向准备好的第一个输出?而且因为write()是较低级别,并且不需要像那样缓冲printf()它首先打印?

Zan*_*ynx 6

你是在自问自答.

printf是缓冲的,write不是.

对于输出到终端,C stdio系统有一个功能,即只要看到换行符就会刷新缓冲区'\n'.有关stdio缓冲的更多信息,请查看文档setvbuf.

但是当输出到文件以提高速度时,stdio系统不会刷新缓冲区.这就是write输出首先出现的原因.

以下是strace在我的Linux系统上运行的一些输出:

fstat(1,{st_mode = S_IFCHR | 0620,st_rdev = makedev(136,1),...})= 0
mmap(NULL,4096,PROT_READ | PROT_WRITE,MAP_PRIVATE | MAP_ANONYMOUS,-1,0)= 0x7f7880b41000
write( 1,"这是一个printf测试\n",22)= 22
写(1,"这是写测试\n\0",22)= 22

fstat是stdio系统检测输出文件描述符1所连接的类型的位置.我相信它看起来st_mode并且看到它是一个角色设备.磁盘文件是块设备.这mmap是stdio缓冲区的内存分配,即4K.然后写入输出.