c printf 缓冲区分析
printf行緩沖區的分析總結
2013-08-18 12:29?5222人閱讀?評論(7)?收藏?舉報 ?分類: app program(9)?版權聲明:本文為博主kerneler辛苦原創,未經允許不得轉載。
??最近在客戶那調試串口的時候,read串口然后printf打印,單字符printf,發現沒有輸出,后來想起來printf這些標準輸入輸出函數也是屬于標準C庫glibc的,
? 這里就要區分一下標準庫函數和系統調用了。
? 系統調用是內核提供給上層程序的接口,能夠實現內核和上層之間的交互,系統調用在內核中的實現是軟中斷的方式,通過相應的中斷服務例程來實現,而標準庫函數是在系統調用的基礎之上封裝的應用程序,完全運行在用戶態,在必要的時候調用系統調用。編寫應用程序可以直接使用應用程序也可以使用庫函數,那為什么還要有庫函數呢。
??以printf為例,在printf的實現中,在調用write之前加入了IO緩沖區,這是一個用戶空間的緩沖,首先要說明一點,系統調用是軟中斷,頻繁調用,需要內核頻繁陷入內核態,這樣的效率不是很高,而printf實際是向用戶空間的IO緩沖寫,在滿足條件的情況下(條件下面會說)才會調用write系統調用,這樣也就提高了內核的效率。
?? 對于普通的文件操作,庫函數因為IO緩沖區,效率高,其他方面與直接調用系統調用無異,但是對于一些特殊的文件,如串口終端以及網絡設備。對于應用程序來將,我們更加希望的是每次的操作能夠真真正正的反映在底層的硬件上,這時我們最好就不要使用類似與printf這樣的帶IO緩沖區的標準庫函數了,而是直接使用系統調用,我上面就是犯了這個錯誤。
?? 說完標準庫函數和系統調用的區別,我們就要具體的分析一下printf。
??? printf是一個行緩沖函數,先寫到緩沖區,滿足條件后,才將緩沖區刷到對應文件中,刷緩沖區的條件如下:
??? 1 緩沖區填滿
??? 2 寫入的字符中有‘\n’ '\r'
??? 3 調用fflush手動刷新緩沖區
??? 4 調用scanf要從緩沖區中讀取數據時,也會將緩沖區內的數據刷新
???
??滿足上面4個條件之一緩沖區就會刷新,,也就是printf會真正調用write來寫入
?? 當我們執行printf的進程或者線程結束的時候會主動調用flush來刷新緩沖區,所以程序結束,也會刷新
?? 如果我們淪落到調用printf后再調用fflush來刷新的話,我感覺還不如調用write來的直接呢
?? 其他的3點都好理解,下面我們就手動來研究一下printf的緩沖區到底有多大?
?? 這就需要我們寫一個小程序來驗證一下,程序如下:
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
??? int i = 0x61;
??? while(1)
??? {? ?
??????? printf("%c", i);?
??????? i++;
??????? i = (i - 0x61) % 26 + 0x61;
??????? usleep(1000);
??? }? ?
??? return 0;
}
在本地機器上編譯這個程序,之后運行,在屏幕第一次輸出結構后ctrl+C殺死,將結果保存在一個文件中,ls -l查看一下這個文件
?我查看這個文件大小是1025個字節,這也就說明printf的緩沖區是1024byte,當寫入第1025字節時刷新緩沖區到終端下。
總結
以上是生活随笔為你收集整理的c printf 缓冲区分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: double free
- 下一篇: 结构体中的malloc 与 free