1. 程式人生 > >Linux 下檔案描述符和開啟檔案之間的關係

Linux 下檔案描述符和開啟檔案之間的關係

2014-07-06 wcdj

檔案描述符和開啟的檔案之間似乎是一一對應的關係,但實際可以多個檔案描述符指向同一開啟檔案,這些檔案描述符可能在相同或不同的程序中開啟。核心維護的三個資料結構:

(1) 程序級的檔案描述符表

(2) 系統級的開啟檔案表

(3) 檔案系統的i-node表

1 程序級的檔案描述符表

針對每個程序,核心為其維護開啟檔案的描述符表,該表的每一條目都記錄了單個檔案描述符的相關資訊:

(a) 控制檔案描述符操作的一組標誌

(b) 對開啟檔案控制代碼的引用

2 系統級的開啟檔案表

核心對所有開啟的檔案維護有一個系統級的描述表(也稱為,開啟檔案表),並將表中各條目稱為開啟檔案控制代碼。一個開啟檔案控制代碼儲存了與一個開啟檔案相關的全部資訊:

(a) 當前檔案偏移量(呼叫read()和write()時更新,或使用lseek()直接修改)

(b) 開啟檔案時所使用的狀態標誌(即,open()的flags引數)

(c) 檔案的訪問模式(如呼叫open()時所設定的只讀模式、只寫模式、或讀寫模式)

(d) 與訊號驅動I/O相關的設定

(e) 對該檔案i-node物件的引用

3 檔案系統的i-node表

每個檔案系統都會為駐留其上的所有檔案建立一個i-node表,包含如下資訊:

(a) 檔案型別(例如,常規檔案、套接字、或FIFO)和訪問許可權

(b) 一個指標,指向該檔案所持有的鎖的列表

(c) 檔案的各種屬性,包括檔案大小以及與不同型別操作相關的時間戳

下圖展示了檔案描述符表、開啟的檔案控制代碼,以及i-node之間的關係


一些結論:

(1) 兩個不同的檔案描述符,若指向同一開啟的檔案控制代碼,將共享同一檔案偏移量。因此,如果通過其中一個檔案描述符來修改檔案偏移量(由read()、write()或lseek()所致),那麼從另一個檔案描述符中也會觀察到這一變化。無論這兩個檔案描述符分屬於不同程序,還是同屬於一個程序,情況都是如此。

(2) 要獲取和修改開啟的檔案標誌(例如,O_APPEND、O_NONBLOCK、O_ASYNC),可執行fcntl()的F_GETFL和F_SETFL操作。

(3) 檔案描述符標誌(即,close-on-exec)為程序和描述符所私有,對這一標誌的修改不會影響同一程序或不同程序中其他檔案描述符。

參考

[1] TLPI 5.4