转:https://blog.csdn.net/qq_25424545/article/details/78772959缓存
今天用fork()写程序时候,忽然发现本身对Printf的缓冲机制仍是有些不够了解,因而来深度解析一下,Printf的缓冲机制究竟是怎么一回事呢?函数
首先printf是库函数,它是由C标准库提供的,它是对系统调用函数write()的一层封装,既然是封装,那它就必定会有改进和性能上的提高,达到方便使用的目的,缓冲机制就是其中的一项改进。为了更加透彻的了解printf函数的缓冲机制,咱们来看下面的两个例子。性能
运行环境:gcc (GCC) 4.4.7spa
代码1:.net
#include<stdio.h>
#include<unistd.h>
int main()
{
printf("hehe\n");
int ret = fork();
if(ret==0)
{
//child
printf("I am child\n");
}
else if(ret<0)
{
printf("Error\n");
}
else
{
printf("I am father\n");
}
return 0;
}
运行结果1: blog
hehe
I am father
I am child继承
代码2:队列
#include<stdio.h>
#include<unistd.h>
int main()
{
printf("hehe");
int ret = fork();
if(ret==0)
{
//child
printf("I am child\n");
}
else if(ret<0)
{
printf("Error\n");
}
else
{
printf("I am father\n");
}
return 0;
}
运行结果2:进程
heheI am father
heheI am child字符串
相信聪明的你能够看出这两个代码块惟一不一样之处在与两个代码开头处的printf,第一个带了\n,第二个并无带,然而输出结果确实大不相同,究其缘由在于printf函数缓冲机制,printf函数实际上只是输出到了标准输出缓冲队列上,并无实实在在的打印到屏幕上,标准输出是行缓冲机制,也就是说,遇到\n,就会刷新缓冲区,输出到屏幕上,在第一个程序中fork以前已经输出,并刷新了缓冲区,所以子进程不会会继承父进程的这个内容,而在第二个程序中,因为没有遇到换行符,因此字符串"hehe"还在缓冲区中,这时子进程的缓冲区里有也有了这个字符串,全部第二个程序会多打印个"hehe"
内核的缓存是在驱动作的,全部调用printf的程序都共享,可是在应用层的c库也作了缓存,这部分缓存是程序独立的
拓展:
行缓冲:见到'\n'刷新缓冲区(例如stdout)