Linux中的檔案描述符與開啟檔案之間的關係

2021-08-07 21:17:49 字數 1968 閱讀 1142

在linux系統中一切皆可以看成是檔案,檔案又可分為:普通檔案、目錄檔案、鏈結檔案、裝置檔案等。檔案描述符(file descriptor)是核心為了高效管理已開啟檔案所建立的索引,其是乙個非負整數(通常是小整數),用於指代被開啟的檔案,所有執行i/o操作的系統呼叫都通過檔案描述符。程式在剛啟動的時候,0是標準輸入,1是標準輸出,2是標準錯誤。如果此時去開啟乙個新的檔案,它的檔案描述符是3。posix要求每次開啟檔案時(含socket)必須使用當前程序中最小的檔案描述符號碼,因此,在網路通訊過程中稍不注意就有可能造成串話。

如下:檔案描述符

用途posix名稱

stdio流

0標準輸入

stdin_fileno

stdin

1標準輸出

stdout_fileno

stdout

2標準錯誤

stderr_fileno

stderr

檔案描述符與開啟的檔案對應模型如下圖:

在編寫檔案操作的或者網路通訊的軟體時,初學者一般可能會遇到「too many open files」的問題。這主要是因為檔案描述符是系統的乙個重要資源,雖然說系統記憶體有多少就可以開啟多少的檔案描述符,但是在實際實現過程中核心會做相應處理的,一般最大開啟檔案數會是系統記憶體的10%(以kb來計算)(稱之為系統級限制),檢視系統級別的最大開啟檔案數可以使用sysctl -a | grep fs.file-max命令檢視。

與此同時,核心為了不讓某乙個程序消耗掉所有的檔案資源,其也會對單個程序最大開啟檔案數做預設值處理(稱之為使用者級限制),預設值一般是1024,使用ulimit -n命令可以檢視。在web伺服器中,通過更改系統預設值檔案描述符的最大值來優化伺服器是最常見的方式之一,具體優化可見linux下檔案描述符。

每乙個檔案描述符會與乙個開啟檔案相對應,同時,不同的檔案描述符也會指向同乙個檔案。相同的檔案可以被不同的程序開啟也可以在同乙個程序中被多次開啟。系統為每乙個程序維護了乙個檔案描述符表,該錶的值都是從0開始的,所以在不同的程序中會看到相同的檔案描述符,這種情況下相同的檔案描述符有可能指向同乙個檔案,也有可能指向不同的檔案。具體要看具體分析,要理解具體其概況如何,需要檢視由核心維護的3個資料結構:

核心對所有開啟的檔案的檔案維護有乙個系統級的描述符**(open file description table)。有時,也稱之為開啟檔案表(open file table),並將**中各條目稱為檔案控制代碼(open file handle)。乙個開啟檔案控制代碼儲存了與乙個開啟檔案相關的全部資訊,如下所示:

下圖展示了檔案描述符、開啟的檔案控制代碼以及i-node之間的關係,圖中,兩個程序擁有諸多開啟的檔案描述符:

在程序a中,檔案描述符1和30都指向了同乙個開啟的檔案控制代碼(標號23)。這可能是通過呼叫dup()、dup2()、fcntl()或者對同乙個檔案多次呼叫了open()函式而形成的。

程序a的檔案描述符2和程序b的檔案描述符2都指向了同乙個開啟的檔案控制代碼(標號73)。這種情形可能是在呼叫fork()後出現的(即,程序a、b是父子程序關係),或者當某程序通過unix域套接字將乙個開啟的檔案描述符傳遞給另乙個程序時,也會發生。再者是不同的程序獨自去呼叫open函式開啟了同乙個檔案,此時程序內部的描述符正好分配到與其他程序開啟該檔案的描述符一樣。

此外,程序a的描述符0和程序b的描述符3分別指向不同的開啟檔案控制代碼,但這些控制代碼均指向i-node表的相同條目(1976),換言之,指向同乙個檔案。發生這種情況是因為每個程序各自對同乙個檔案發起了open()呼叫。同乙個程序兩次開啟同乙個檔案,也會發生類似情況。

linux檔案描述符與開啟檔案的關係

1.概述 在linux系統中一切皆可以看成是檔案,檔案又可分為 普通檔案 目錄檔案 鏈結檔案和裝置檔案。檔案描述符 file descriptor 是核心為了高效管理已被開啟的檔案所建立的索引,其是乙個非負整數 通常是小整數 用於指代被開啟的檔案,所有執行i o操作的系統呼叫都通過檔案描述符。程式剛...

Linux中的檔案描述符與開啟檔案之間的關係

1.概述 在linux系統中一切皆可以看成是檔案,檔案又可分為 普通檔案 目錄檔案 鏈結檔案和裝置檔案。檔案描述符 file descriptor 是核心為了高效管理已被開啟的檔案所建立的索引,其是乙個非負整數 通常是小整數 用於指代被開啟的檔案,所有執行i o操作的系統呼叫都通過檔案描述符。程式剛...

Linux中的檔案描述符與開啟檔案之間的關係

核心 kernel 利用檔案描述符 file descriptor 來訪問檔案。檔案描述符是非負整數。開啟現存盤案或新建檔案時,核心會返回乙個檔案描述符。讀寫檔案也需要使用檔案描述符來指定待讀寫的檔案。1.概述 在linux系統中一切皆可以看成是檔案,檔案又可分為 普通檔案 目錄檔案 鏈結檔案和裝置...