天天看點

無緩沖I/O與有緩沖I/O差別

無緩沖I/O :不是核心不提供緩沖,而是對于使用者層來說,沒有提供緩存,而對核心來說還是有緩存的

資料:資料流->核心緩存->磁盤

有緩沖I/O:是指在使用者層上再建立了一層緩存區(流緩存區),目的是為了減少read,write等系統調用的使用次數,降低系統開銷。

資料:資料流->流緩存區->核心緩存->磁盤

e.g當用fwrite函數網磁盤寫資料時,先把資料寫入流緩沖區中,當達到一定條件,比如流緩沖區滿了,或重新整理流緩沖,這時候才會把資料一次送往核心提供的塊緩沖,再經塊緩沖寫入磁盤。(雙重緩沖)

标準IO就是帶緩存的IO,提供了三種類型的緩存

全緩存:當填滿标準IO緩存後才執行IO操作,磁盤上的檔案通常都是全緩存的

行緩存:當輸入輸出遇到換行符或緩存滿時,才執行IO操作,stdin和stdout通常是行緩存的

無緩存:stderr通常是無緩存的,因為它必須盡快輸出

是什麼樣的緩沖跟使用那個函數沒有關系 , 而跟你讀寫什麼類型的檔案有關系 .  帶 緩存的檔案操作時标準C庫的實作,第一次調用帶緩存的檔案操作函數時,标準庫會自動配置設定記憶體并且讀出一段固定大小的記憶體存儲在緩存中。以後每次的讀寫操作并不是針對硬碟上的檔案直接進行的,而是針對記憶體中的緩存的。

思考:為什麼總是要将資料從使用者緩存區弄到核心緩沖區或者相反呢?

核心緩沖存在的價值: 使用者是運作在使用者空間的,不能直接操作核心緩沖區的資料。使用者進行到系統調用時,會由使用者态變到核心态,待核心使用完後再變到使用者态。

摘錄:

應用緩沖技術能很明顯的提高系統效率。核心與外圍裝置的資料交換,核心與使用者空間的資料交換都是比較費時的,使用緩沖區就是為了優化這些費時的操作。其實核心到使用者空間的操作本身是不buffer的,是由I/O庫用buffer來優化了這個操作。比如read本來從核心讀取資料時是比較費時的,是以一次取出一塊,以避免多次陷入核心。

      應用核心緩沖區的 主要思想就是一次讀入大量的資料放在緩沖區,需要的時候從緩沖區取得資料。

      管理者模式和使用者模式之間的切換需要消耗時間,但相比之下,磁盤的I/O操作消耗的時間更多,為了提高效率,核心也使用緩沖區技術來提高對磁盤的通路速度。磁盤是資料塊 的集合,核心會對磁盤上的資料塊做緩沖。核心将磁盤上的資料塊複制到核心緩沖區中,當一個使用者空間中的程序要從磁盤上讀資料時,核心一般不直接讀磁盤,而 是将核心緩沖區中的資料複制到程序的緩沖區中。當程序所要求的資料塊不在核心緩沖區時,核心會把相應的資料塊加入到請求隊列,然後把該程序挂起,接着為其 他程序服務。一段時間之後(其實很短的時間),核心把相應的資料塊從磁盤讀到核心緩沖區,然後再把資料複制到程序的緩沖區中,最後喚醒被挂起的程序。

      注:了解核心緩沖區技術的原理有助于更好的掌握系統調用read&write,read把資料從核心緩沖區複制到程序緩沖區,write把資料從程序緩沖區複制到核心緩沖區,它們不等價于資料在核心緩沖區和磁盤之間的交換。

      從理論上講,核心可以在任何時候寫磁盤,但并不是所有的write操作都會導緻核心的寫動作。核心會把要寫的資料暫時存在緩沖區中,積累到一定數量後再一 次寫入。有時會導緻意外情況,比如斷電,核心還來不及把核心緩沖區中的資料寫道磁盤上,這些更新的資料就會丢失。

      應用核心緩沖技術導緻的結果是:提高了磁盤的I/O效率;優化了磁盤的寫操作;需要及時的将緩沖資料寫到磁盤。