stdio流緩衝區

Dylaris發表於2024-10-02

檔案流緩衝區

每個程序都各自維護一個檔案流表,和檔案描述符表類似,並且這些檔案流都有自己對應的緩衝區

緩衝區的設計就是為了減少磁碟io,加快io的速度

緩衝區模式

透過setvbuf或者setbuf兩個函式設定緩衝區的模式

無緩衝區

就是禁用緩衝區的意思,這種模式下,就相當於直接呼叫write函式,不過在呼叫write之前可能還要處理一些格式化輸出等問題,這是和直接呼叫write的一個小區別

行緩衝區

當標準輸出(或者輸入)定向到終端時,預設採用行緩衝模式,就是接收到換行符就重新整理緩衝區

塊緩衝區

當緩衝區的資料達到一個塊的大小時,重新整理緩衝區,重定向時,預設使用塊緩衝區

全緩衝區

當資料填滿緩衝區時,重新整理緩衝區

總結對比

特性 無緩衝區(No Buffering) 行緩衝區(Line Buffering) 塊緩衝區(Block Buffering) 全緩衝區(Full Buffering)
定義 資料不經過緩衝,直接寫入目標裝置 每當輸入一行資料時,才進行輸出 資料以塊為單位進行緩衝,達到塊大小後輸出 資料在緩衝區中,直到填滿後一次性輸出
重新整理時機 每次寫入操作都立即重新整理 每當遇到換行符時重新整理 當緩衝區滿或達到特定塊大小時重新整理 緩衝區滿或顯式呼叫重新整理時才輸出
記憶體使用 無額外記憶體開銷 較少的記憶體開銷 預定的塊大小記憶體開銷 較大的記憶體開銷,通常是輸出的總大小
效能 頻繁I/O操作,效能較低 適合逐行處理,效能適中 減少I/O操作,提高效能 適合長時間不需要輸出的場景,效能較高
適用場景 實時處理要求高的場景 互動式程式或逐行輸出 大資料處理或檔案寫入 批處理或需要大量輸出的場景
實時反饋 反饋及時 逐行反饋 反饋延遲,直到塊大小達到 反饋延遲,直到緩衝區滿

與fork和exit之間的互動

fork函式用於建立子程序,這樣的話子程序會複製一份父程序的stdio流緩衝區

exit函式在呼叫_exit函式前,會重新整理所有stdio流緩衝區

這兩個配合起來,有時候就會發現有的輸出列印了兩份,這是因為緩衝區沒有及時重新整理的原因,有以下幾種辦法

  • 可以設定緩衝區模式
  • 使用fflush立即重新整理
  • 父程序使用exit函式在程式結束後重新整理,子程序使用_exit函式退出,該函式不重新整理緩衝區

所以在有多程序的情況下使用stdio流,要注意緩衝區的模式,以及何時重新整理緩衝區,避免出現意外情況

相關文章