I/O模型前期知識

在這裏插入圖片描述

以此圖中I\O阻塞模型爲例

圖中操作體指進程/線程/協程。用戶運行程序要求訪問文件,即創建操作體調用內核中開放的數據接口訪問硬件空間的文件,通過文件名找到文件的inode號碼,通過inode號碼得到inode信息,通過inode信息找到文件所在的區域(即文件描述符),確定文件位置。

將文件從硬件空間拷貝至內核空間的緩衝區,然後cpu將數據從內核空間緩衝區拷貝到用戶的地址空間。用戶即可對文件進行讀寫操作。
若是寫操作,寫完之後會通過將cpu修改後的文件從用戶緩衝區拷貝回內核緩衝區,再拷貝回硬件保存。
圖中等待數據準備即等到找到文件所在區域即返回文件描述符。

下圖爲用戶想訪問磁盤文件順序:
在這裏插入圖片描述

1.I\O操作是什麼?

I\O模型是輸入輸出流。 不管socket、還是FIFO、管道、終端等,對於LInux來說、一切都是文件、一切都是流。 在信息交換的過程中、我們都是對這些流進行數據的收發操作、簡稱爲I/O操作(input and output)、往流中讀出數據系統調用read、寫入數據系統調用write。

在計算機中有許許多多的流,因此在程序操作中,需要針對指定的流進行操作的時候,我們需要創建對應的文件描述符,即通常所說的fd(file descriptor)。對這個fd的操作、就是對這個文件(流)的操作,我們創建一個socket/讀寫一個文件,通過系統調用會返回一個文件描述符,那麼接下來的操作就會轉化爲對這個描述符的操作,這就是IO操作。

2.文件描述符是什麼?

文件描述符(File descriptor)是計算機科學中的一個術語,是一個用於表述指向文件的引用的抽象化概念。
文件描述符在形式上是一個非負整數。實際上,它是一個索引值,指向內核爲每一個進程所維護的該進程打開文件的記錄表。當程序打開一個現有文件或者創建一個新文件時,內核向進程返回一個文件描述符。在程序設計中,一些涉及底層的程序編寫往往會圍繞着文件描述符展開。但是文件描述符這一概念往往只適用於UNIX、Linux(一切皆文件)這樣的操作系統。

在linux內核當中一個進程通過task_struct結構體描述,而打開的文件則用file結構體描述,打開文件的過程也就是對file結構體的初始化的過程。在打開文件的過程中會將inode部分關鍵信息填充到file中,特別是文件操作的函數指針。在task_struct中保存着一個file類型的數組,而用戶態的文件描述符其實就是數組的下標。這樣通過文件描述符就可以很容易到找到file,然後通過其中的函數指針訪問數據。

例如我們以Ext2文件系統的寫數據爲例,在調用用戶態的寫數據接口的時候,需要傳入文件描述符。內核根據文件描述符找到file,然後調用函數接口(file->f_op->write)文件磁盤數據。其中file結構體的f_op指針就是在打開文件的時候通過inode初始化的。

3.內核空間和用戶空間是什麼?

在這裏插入圖片描述
如圖所示,Linux內核由系統內的所有進程共享,每個進程都有4G的虛擬地址空間。內核空間中存放的是內核代碼和所有的內核模塊以及內核所維護的數據。而進程的用戶空間中存放的是用戶程序的代碼和數據。不管是內核空間還是用戶空間,它們都處於虛擬空間中。

整個linux內部結構可以分爲三部分,從最底層到最上層依次是:硬件–>內核空間–>用戶空間

用戶運行一個程序,該程序創建的進程開始時運行自己的代碼,處於用戶態。如果要執行文件操作、網絡數據發送等操作必須通過write、send等系統調用,這些系統調用會調用內核的代碼。進程會切換到0級別,然後進入3G-4G中的內核地址空間去執行內核代碼來完成相應的操作。內核態的進程執行完後又會切換到3級別,回到用戶態。這樣,用戶態的程序就不能隨意操作內核地址空間,具有一定的安全保護作用。這說的保護模式是指通過內存頁表操作等機制,保證進程間的地址空間不會互相沖突,一個進程的操作不會修改另一個進程地址空間中的數據。

4.I\O操作爲什麼需要調用內核?

Linux系統中內核權限最高爲0級,用戶權限低爲3級。數據存放在硬件中,只有操作系統(內核)纔有權限可以訪問硬件,用戶(應用程序)不能直接訪問硬件,因此用戶執行代碼訪問數據需要經過內核。

緩存I/O

緩存 I/O 又被稱作標準 I/O,大多數文件系統的默認 I/O 操作都是緩存 I/O。在 Linux 的緩存 I/O 機制中,操作系統會將 I/O 的數據緩存在文件系統的頁緩存( page cache )中,也就是說,數據會先被拷貝到操作系統內核的緩衝區中,然後纔會從操作系統內核的緩衝區拷貝到應用程序的地址空間。

系統內核對磁盤的讀寫都會提供一個塊緩衝,當用write函數對其寫數據時,直接調用系統調用,將數據寫入到塊緩衝進行排隊,當塊緩衝達到一定的量時,纔會把數據寫入磁盤。因此所謂的不帶緩衝的I/O是指進程不提供緩衝功能。每調用一次write或read函數,直接系統調用。
而帶緩衝的I/O是指進程對輸入輸出流進行了改進,提供了一個流緩衝,當用fwrite函數網磁盤寫數據時,先把數據寫入流緩衝區中,當達到一定條件,比如流緩衝區滿了,或刷新流緩衝,這時候纔會把數據一次送往內核提供的塊緩衝,再經塊緩衝寫入磁盤。
因此,帶緩衝的I/O在往磁盤寫入相同的數據量時,會比不帶緩衝的I/O調用系統調用的次數要少。

用戶空間沒法直接訪問內核空間的,內核態到用戶態的數據拷貝 爲什麼存在緩存衝區?
因爲頻繁複制需要花費時間。

緩存I/O的優點:1)在一定程度上分離了內核空間和用戶空間,保護系統本身的運行安全;2)可以減少讀盤的次數,從而提高性能。

緩存I/O的缺點:數據在傳輸過程中需要在應用程序地址空間和緩存之間進行多次數據拷貝操作,這些數據拷貝操作所帶來的CPU以及內存開銷是非常大的。

參考文獻

[1] IO模型前期準備理論
[2]用戶態和內核態的理解和區別
[3]Linux虛擬文件系統(VFS)
[4]淺談IO概念與IO模型
[5]Linux 虛擬文件系統(VFS)在文件系統中的作用
[6]I/O訪問方式

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章