使用者程序執行在使用者控制項,而磁碟只能被核心直接訪問。當執行系統呼叫時,需要在核心中執行**。系統呼叫的開銷不僅僅是因為資料的傳輸。當執行核心**時,cpu需要切換到超級使用者模式,需要建立額外的堆疊和記憶體環境,執行完系統呼叫時,cpu要切換回使用者模式,把堆疊和記憶體環境還原為原來的使用者模式執行狀態。這種頻繁的使用者態和核心態切換將消耗更多的時間。
為了提高i/o的效率,我們可以使用更大的緩衝區來一次讀取更多的資料。這樣會減少使用者態和核心態之間的切換,提高程式的i/o效率。
編寫who命令時,如果我們一次讀取乙個utmp物件的記憶體,讀取10個登入使用者就需要呼叫10次read系統呼叫。但是,如果我們一次讀取5個物件資料,那麼2次系統呼叫就可以完任務。
#include #include #include #include #include #include #define readsize 16 // 定義緩衝區大小
#define utmpsize sizeof(struct utmp)
static char utmpbuf[readsize * utmpsize]; // 緩衝區陣列
static int rec_count = 0; // 讀取到的物件數目
static int cur_count = 0; // 已經輸出的物件數目
static int fd_utmp = -1; // 檔案描述符
void show_info(struct utmp* utbuf)
int utmp_open(char * filename)
int utmp_reload()
void utmp_close()
struct utmp* utmp_next()
int main()
while((ubufp = utmp_next()) != null)
show_info(ubufp);
utmp_close();
return 0;
}
上述是改進過who命令。每次讀取多個資料,放入utmp陣列。之後對陣列逐個進行輸出,直到檔案內容為空。
由於將緩衝區置為16個物件的大小。系統呼叫的次數將會大大降低。
與使用者程式的緩衝技術類似,核心在對磁碟等硬體進行i/o操作時也採用緩衝技術。磁碟的i/o操作所消耗的時間很多,與一次讀取多個utmp物件類似,核心將磁碟的資料塊複製到核心緩衝區中,當乙個使用者空間的程序要從磁碟讀取資料時,核心一般不直接讀取磁碟,而是將核心緩衝區中的資料複製到程序的緩衝區中。
當程序所要求的資料塊不在核心緩衝區時,核心會將相應的資料塊加入請求列表中,並把程序掛起,接著為其他程序服務。一段很短的等待時間之後,核心把相應的資料塊從磁碟讀到核心緩衝區,然後再把資料複製到程序的緩衝區中,最後喚醒程序。
但是,理論上,核心可以在任何時候寫磁碟,並不是所有的write操作都會導致核心的寫動作。核心一般把要寫的資料暫時存在緩衝區中,積累到一定的數量之後再一次寫入。當突然斷電或者其他突發情況發生時,核心會來不及寫入磁碟,此時更新的資料就會丟失。
Linux系統程式設計 檔案IO緩衝
e 核心緩衝 緩衝區快取記憶體 read 和write 系統呼叫在操作磁碟檔案時不會直接發起磁碟訪問,而僅僅在使用者空間緩衝區和核心緩衝區快取記憶體之間複製資料。例如 write fd,abc 3 write會立即返回。在後續某個時刻,核心會將其緩衝區中的資料寫入磁碟。在此期間,另一程序試圖讀取該檔...
Linux系統程式設計(三)
ipc 程序間通訊 檔案型別 檔案 d 目錄 l 符號鏈結 偽檔案 s 套接字 b 塊裝置 c 字元裝置 d 管道 管道 是一種最基本的ipc機制,作用於有血緣關係的程序之間,完成資料傳遞。呼叫pipe系統函式即可建立乙個管道,有如下特質 本質是乙個偽檔案 實為核心緩衝區 由兩個檔案描述符引用,乙個...
Linux系統程式設計(標準I O緩衝區)
標準i o庫提供緩衝的目的是盡可能地減少使用read和write呼叫的次數。它也對每個i o流自動地進行緩衝管理,從而避免了應用程式需要考慮這一點所帶來的麻煩。不幸的是,標準i o庫最令人迷惑的也是它的緩衝。標準i o提供了三種型別的緩衝 1 全緩衝 當在輸入和輸出中遇到換行符時,標準i o庫執行i...