轉: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)