深入理解C语言的缓冲区

86 阅读1分钟

示例

#include<stdio.h>
#include<unistd.h>
#include<string.h>
int main()
{
    const char* msg="hello 标准输出\n";
    write(1,msg,strlen(msg));
    printf("hello printf\n");
    fprintf(stdout,"hello fprintf\n");
    fputs("hello fputs\n",stdout);
    fork();
}

结果

image.png

image.png

细心的你可以发现,调用fork时向stdout打印时只打印了一份,重定向到txt文件里面却打印了两份,但是write调用的也打印的是一份这是为什么呢?

缓冲区

缓冲区分为用户级缓冲区和内核级缓冲区,在向标准输出打印时,先在用户级缓冲区保存,再刷新到内核级缓冲区最后才让我们看到。 对于标准输出和向文件里写入是有不同的刷新策略的,分别是行刷新,和全刷新

答案

对于write,这是一个系统接口,直接将用户级的缓冲区刷新到了内核里面,当调用fork时,用户级缓冲区的数据根本就没有,所以只打印了父进程的数据,对于其他的接口,当向标准输出打印时,是按换行刷新的,遇到换行符就直接刷新了,子进程就没有复制用户级缓冲区的数据,向文件里打印时,数据一直在用户级缓冲区里面,没有被刷新到内核缓冲区里面,所以子进程会复制这个数据,程序结束后一同打印到了文件里面,也就形成了上面的现象。