1. 程式人生 > 實用技巧 >Linux核心緩衝技術

Linux核心緩衝技術

概述


 核心空間與外圍裝置交換資料,使用者空間與核心空間交換資料實際上是非常消耗時間的,應該儘量減少它們之間相互訪問的次數,就應用了緩衝技術。其本質就是一次性讀取大量資料(順序讀寫)進緩衝,當需要資料的時候進入緩衝區讀取資料,這樣能夠大大減少消耗的時候被消耗的時間,所以核心緩衝技術對於檔案IO是非常重要的。

 linux中的fopen函式是open函式的封裝,fopen使用了FILE結構體儲存緩衝資料,在進行read和write的時候減少了使用者態和核心態的切換。open沒有緩衝,每次讀操作都直接從檔案系統中獲取資料,在進行read和write的時候每次都需要進行核心態和使用者態的切換。當順序訪問檔案,fopen系列的函式要比直接呼叫open系列快;如果隨機訪問檔案open要比fopen快。
 在上圖中可以看到open每次開啟檔案都會產生一個結構體file來儲存檔案的讀寫資訊,即使對於同時開啟同一個檔案,其結構體資訊是不一樣的。

標準IO緩衝區

 1.不緩衝:一旦有資料,立即同步到外部裝置。
 2.全緩衝:(普通檔案的預設型別);
  a.一旦資料填滿了緩衝區,立即同步到外部裝置;
  b.程式正常退出時,立即同步到外部裝置;
  c.遇到 fflush() 強制同步時,立即同步到外部裝置;
  d.關閉檔案時,立即同步到外部裝置;
  e.讀取檔案時 , 立即同步到外部裝置;
 3.行緩衝:(最多隻能緩衝一行)
  a.一旦填滿,立即同步到外部裝置;
  b.程式正常退出時,立即同步到外部裝置;
  c.遇到 fflush() 強制同步時,立即同步到外部裝置;
  d.關閉檔案時,立即同步到外部裝置;
  e.讀取檔案時 , 立即同步到外部裝置;
  f.一旦遇到 '\n' 時, 立即同步到外部裝置;

相關API

setbuf ( 設定檔案流的緩衝區 )
    標頭檔案:
        #include <stdio.h>
    定義函式:
        void setbuf(FILE * stream, char * buf);
    引數分析:
         stream --> 為指定的檔案流
         buf --> 自定的緩衝區起始地址 
     無返回
        
setvbuf ( 設定檔案流的緩衝區)
    標頭檔案:
        #include <stdio.h>
    定義函式:
        int setvbuf(FILE * stream, char * buf, int mode, size_t size);
    引數分析:
        stream --> 指定的檔案流 
        buf --> 指向自定的緩衝區起始地址
        size --> 為緩衝區大小
        mode --> 有下列幾種
            _IONBF 無緩衝 IO
            _IOLBF 以換行為依據的無緩衝 IO
            _IOFBF 完全無緩衝 IO. 如果引數 buf 為 NULL 指標, 則為無緩衝 IO.
    返回值:
        成功返回 0 
        失敗返回 非零 , 錯誤號碼會被設定

使用程式碼

#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main()
{
 
   char buff[1024];
 
   memset( buff, '\0', sizeof( buff ));
 
   fprintf(stdout, "啟用全緩衝\n");
   setvbuf(stdout, buff, _IOFBF, 1024);
 
   fprintf(stdout, "這裡是 runoob.com\n");
   fprintf(stdout, "該輸出將儲存到 buff\n");
   fflush( stdout );
 
   fprintf(stdout, "這將在程式退出時出現\n");
   fprintf(stdout, "最後休眠五秒鐘\n");
 
   sleep(5);
 
   return(0);
}

https://www.runoob.com/cprogramming/c-function-setvbuf.html

總結

 1.通常磁碟上的檔案是全緩衝區的;
 2.標準輸入和標準輸入在指向終端裝置時是行緩衝,而指向檔案時,則是全緩衝的;
 3.為了儘可能顯示錯誤資訊,標準錯誤是不帶緩衝的。