Linux 中一切皆檔案,比如 C++ 原始檔、視訊檔、Shell指令碼、可執行檔案等,就連鍵盤、顯示器、滑鼠等硬體裝置也都是檔案。
一個 Linux 進程可以開啟成百上千個檔案,為了表示和區分已經開啟的檔案,Linux 會給每個檔案分配一個編號(一個 ID),這個編號就是一個整數,被稱為
檔案描述符(File Descriptor)。
這只是一個形象的比喻,為了讓讀者容易理解我才這麼說。如果你也僅僅理解到這個層面,那不過是淺嚐輒止而已,並沒有看到檔案描述符的本質。
本篇文章的目的就是撥雲見霧,從底層實現的角度來給大家剖析一下檔案描述符,看看檔案描述如到底是如何表示一個檔案的。
不過,閱讀本篇文章需要你有C語言程式設計基礎,至少要理解陣列、指標和結構體;如果理解記憶體,那就更好了,看了這篇文章你會醍醐灌頂。
好了,廢話不多說,讓我們馬上進入正題吧。
Linux 檔案描述符到底是什麼?
一個 Linux 進程啟動後,會在核心空間中建立一個 PCB 控制塊,PCB 內部有一個檔案描述符表(File descriptor table),記錄著當前進程所有可用的檔案描述符,也即當前進程所有開啟的檔案。
核心空間是虛擬地址空間的一部分,想死磕的讀者請猛擊《C語言記憶體精講》,不想糾纏細節的讀者可以這樣理解:進程啟動後要佔用記憶體,其中一部分記憶體分配給了檔案描述符表。
除了檔案描述符表,系統還需要維護另外兩張表:
-
開啟檔案表(Open file table)
-
i-node 表(i-node table)
檔案描述符表每個進程都有一個,開啟檔案表和 i-node 表整個系統只有一個,它們三者之間的關係如下圖所示。