stdio的緩衝區

2021-07-27 02:51:08 字數 1527 閱讀 6613

原因為多種,有兩個重點:

1.  從記憶體中讀取資料比從檔案中讀取資料要快得多(這只是一種淺顯地說法,但確實能說明問題)。

2.  對檔案的讀寫需要用到open、read、write等系統底層函式,而使用者程序每呼叫一次系統函式都要從使用者態切換到系統態,等執行完畢後再返回使用者態,這種切換要花費一定時間成本(對於高併發程式而言,這種狀態的切換會影響到程式效能)。

舉個例子,如果程式需要處理10k個整數(或者10k個字串等等),而這些整數事先存在某個檔案中,如果程式每處理乙個整數就要從檔案中讀乙個整數(read系統呼叫),那麼每次都要進行硬體i/o、程序狀態切換等操作,這樣效率是非常低下的。如果每次從檔案中讀出1k個整數到記憶體,程式從記憶體中讀取資料並處理,那麼程式的效能會明顯提高,儲存這1k個整數的記憶體區域就是乙個緩衝區。

由於目前計算機體系結構的限制,有時必須採用某些低效的手段。利用低效的手段一次性讀出適量的資料到記憶體,以後的各種操作就只針對記憶體中的資料展開,從而實現對低效手段的緩衝,提高效率,這種機制稱為緩衝機制,而記憶體中儲存資料的區域就稱為緩衝區。

stdio庫(libc庫的一部分)中的函式已經對檔案實現了緩衝機制,並高度優化,可以直接應用到很多專案中。

fread函式的緩衝機制中有如下幾個重要的變數:

1.   pbase:指向緩衝區的指標

2.   nbufsize:緩衝區長度

3.   ptoread:指向緩衝區中未讀取資料的指標

4.   nbyteleft:緩衝區中未讀取資料位元組數

如圖所示,紅色區域表示已經讀入資料的緩衝區,灰色表示空閒的緩衝區。預設緩衝區一般為4096位元組(緩衝區可以由使用者指定,詳見後文),當然,這個長度可以根據檔案長度靈活地變化。

即使使用者讀取了乙個位元組的資料,fread也會事先從檔案中讀取緩衝區大小的資料來填充緩衝區,當然,如果檔案長度小於緩衝區大小,那麼檔案的全部內容都會被讀入緩衝區。

當緩衝區有了資料,fread就可以從緩衝區中讀取資料了。設ncount是要讀入的資料長度,nfilesize是檔案的長度,在初始狀態下(即在第一次執行fread函式時),ptoread= pbase,nbyteleft = filesize > nbufsize?nfilesize:nbufsize。

如果ncount小於nbyteleft,那麼每次從緩衝區的ptoread位置拷貝ncount個位元組到使用者定義的空間中去(即fread的第乙個引數指向的空間),拷貝之後將ptoread向後移動ncount個位元組,並將nbyteleft減少ncount,當nbyteleft為零時,fread將重新呼叫系統函式讀取檔案來重新整理緩衝區(各引數又回到了一開始的狀態)。

如果ncount大於nbyteleft,需要分多次才能將資料拷貝到使用者定義的空間中,先從緩衝區中讀取nbyteleft個位元組,並重新整理緩衝區,再讀取剩下的位元組,顯然這樣的開銷更大。這裡需要注意的是,當一次讀入的資料長度超過緩衝區大小時(如大於4k),fread函式將不再採用緩衝機制。所以用fread讀資料時,如何確定資料的長度應該三思而行。

上面只是fread函式緩衝機制的乙個籠統的介紹,而具體的機制是怎麼樣的呢?聰明的讀者可以自己試著實現一下。

併發讀寫檔案引起的資料正確性問題。

php 緩衝區,PHP的輸出緩衝區

1 什麼是緩衝區?緩衝區的作用是把輸入或者輸出的內容先放進記憶體,而不顯示或者讀取,最本質的作用就是協調高速cpu和相對緩慢的io裝置 磁碟等 的運作。2 php在執行的時候,在什麼地方有用到緩衝區?當執行php的時候,如果碰到了echo print r之類的會輸出資料的 php就會將要輸出的資料放...

輸入緩衝區與輸出緩衝區

本博文通過一段程式來理解輸入緩衝區與輸出緩衝區。程式如下 author wanghao created time thu 17 may 2018 06 03 12 ampdt file name test.c description include int main int argc,const c...

使用者程序緩衝區和核心緩衝區

常常聽到有程式設計師會跟你討論 我們在讀寫檔案的時候,系統是有快取的 但實際上有一部分人把使用者程序緩衝區和系統空間的緩衝區的概念混淆了,包括這兩種緩衝區的用法和所要解決的問題,還有其它類似的概念。本文就來區分一下不同的緩衝區概念 主要針對類unix平台 使用者程序和作業系統的關係 首先我用一張圖來...