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.為了儘可能顯示錯誤資訊,標準錯誤是不帶緩衝的。