標準IO緩衝詳解全緩衝 行緩衝 不緩衝

2022-08-17 13:48:20 字數 2046 閱讀 7796

標準i/o庫提供緩衝的目的是盡可能地減少使用read和write呼叫的次數。他也對每個i/o流自動地進行緩衝管理,從而避免了應用程式需要考慮這一點所帶來的麻煩。不幸的是,標準i/o庫最令人迷惑的也是他的緩衝。

標準i/o提供了三種型別的緩衝:

1、全緩衝。這種情況下,在填滿標準i/o緩衝區後才進行實際i/o操作。對於駐留在磁碟上的檔案通常是由標準i/o庫實施全緩衝。乙個流上執行第一次i/o操作時,相關標準i/o函式通常呼叫malloc獲得需使用的緩衝區。

術語沖洗說明i/o緩衝區的寫操作。緩衝區可由標準i/o例程自動沖洗,或者可以呼叫函式fflush沖洗乙個流。值得引起注意的是在unix環境中,flush有兩種意思。在標準i/o庫方面,flush意味著將緩衝區中的內容寫到磁碟上。在終端驅動程式方面flush表示丟棄已儲存在緩衝區中的資料。

2、行緩衝。在這種情況下,當在輸入和輸出中遇到換行符(『\n』)時,標準i/o庫執行i/o操作。這允許我們一次輸出乙個字元,但只有在寫了一行之後才進行實際i/o操作。當流涉及乙個終端時,通常使用行緩衝。

對於行緩衝有兩個限制。第一,因為標準i/o庫用來收集每一行的緩衝區的長度是固定的,所以只要填滿了緩衝區,那麼即使沒有寫乙個換行符,也進行i/o操作。第二,任何時候只要通過標準i/o庫要求從a乙個不帶緩衝的流,或者b乙個行緩衝的流得到輸入資料,那麼就會造成沖洗所有行緩衝輸出流。在b中帶了乙個在括號中的說明,其理由是,所需的資料可能已在緩衝區中,他並不需求在需要資料時才從核心讀資料。很明顯,從不帶緩衝的乙個流中進行輸入要求當時從核心得到資料。

3、不帶緩衝。標準i/o庫不對字元進行緩衝儲存。例如,如果用i/o函式fputs寫15個字元到不帶緩衝的流中,則該函式很可能用write系統呼叫函式將這些字元立即寫至相關聯的開啟檔案中。

標準出錯流stderr通常是不帶緩衝的,這就使得出錯資訊可以盡快顯示出來,而不管它們是否含有乙個換行符。

iso c要求下列緩衝特徵:

當且僅當標準輸入和標準輸出並不涉及互動式裝置使,他們才是全緩衝的。

標準出錯絕不會使全緩衝的。

但是,這並沒有告訴我們如果標準輸入和標準輸出涉及互動式裝置時,他們是不帶緩衝的還是行緩衝的;以及標準出錯時不帶緩衝的還是行緩衝的。很多系統預設使用下列型別的緩衝:

標準出錯是不帶緩緩衝的。

如若是涉及終端裝置的其他流,則他們是行緩衝的;否則是全緩衝的。

對任何乙個給定的流,如果我們並不喜歡這些系統預設的情況,則可呼叫下列函式中的乙個更改緩衝型別:

void setbuf(file *restrict fp, char *restrict buf)

int setvbuf(file *restrict fp, char *restrict buf,int mode,size_t size)

看個小例子

源程式:

#include

#include

#include

int globa = 4;

int main (void )

else if (pid == 0)else

printf("parent did not changde\n");

printf("globa = %d vari = %d\n",globa,vari);

exit(0);

}執行結果:

輸出到標準輸出

before fork

child changed

globa = 5 vari = 4

parent did not changde

globa = 4 vari = 5

重定向到檔案時before fork輸出兩邊

before fork

child changed

globa = 5 vari = 4

before fork

parent did not changde

globa = 4 vari = 5

分析直接執行程式時標準輸出是行緩衝的,很快被新的一行沖掉。而重定向後,標準輸出是全緩衝的。當呼叫fork時before fork這行仍儲存在緩衝中,並隨著資料段複製到子程序緩衝中。這樣,這一行就分別進入父子程序的輸出緩衝中,餘下的輸出就接在了這一行的後面。

標準I O緩衝 全緩衝 行緩衝 無緩衝

說明 我只對網路資源進行了整合,方便學習 基於流的操作最終會呼叫read或者write函式進行i o操作。為了使程式的執行效率最高,流物件通常會提供緩衝區,以減少呼叫系統i o庫函式的次數。基於流的i o提供以下3種緩衝 全緩衝 直到緩衝區被填滿,才呼叫系統i o函式。對於讀操作來說,直到讀入的內容...

標準I O緩衝 全緩衝 行緩衝 無緩衝

某日一朋友寫了乙個hello world 出不來結果,如下 include intmain int argc,char argv 注意到,在 中printf語句列印的字串最後沒有帶換行符,而且最後呼叫了 exit函式,這導致了在終端螢幕上顯示不出來字串 hello world 首先介紹一下unix裡...

標準I O緩衝 全緩衝 行緩衝 無緩衝

說明 我只對網路資源進行了整合,方便學習 基於流的操作最終會呼叫read或者write函式進行i o操作。為了使程式的執行效率最高,流物件通常會提供緩衝區,以減少呼叫系統i o庫函式的次數。基於流的i o提供以下 3種緩衝 全緩衝 直到緩衝區被填滿,才呼叫系統i o函式。對於讀操作來說,直到讀入的內...