Printf的緩沖機制


https://blog.csdn.net/qq_25424545/article/details/78772959

 今天用fork()寫程序時候,突然發現自己對Printf的緩沖機制還是有些不夠了解,於是來深度解析一下,Printf的緩沖機制到底是怎么一回事呢?

       

       首先printf是庫函數,它是由C標准庫提供的,它是對系統調用函數write()的一層封裝,既然是封裝,那它就一定會有改進和性能上的提升,達到方便使用的目的,緩沖機制就是其中的一項改進。為了更加透徹的了解printf函數的緩沖機制,我們來看下面的兩個例子。

運行環境:gcc (GCC) 4.4.7

代碼1:

#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: 

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)

全緩沖:見到'\n'不刷新,直到顯示fflush()、緩沖區滿或者退出才會刷新緩沖區(例如輸出文件)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM