目前學習到的是乙個檔案描述符對應著乙個開啟的檔案,似乎是對應的關係。但是實際上並不是這樣的。多個檔案描述符指向同乙個開啟的檔案,是可能的也是必要的。這些檔案描述符可以在相同或者不同的程序中開啟。
要理解具體情況,需要檢視核心維護的3個資料結構。
程序級的檔案描述符表
系統級的開啟檔案表
檔案系統的i-node表
控制檔案描述符操作的一組標誌。(目前,此類標誌僅定義了乙個,即close-on-exec標誌)
開啟檔案控制代碼的引用
核心對所有開啟的檔案維護有乙個系統級的描述符**(open file description table)。有時也稱之為開啟檔案表(open file table),並將表中各條目稱之為開啟檔案控制代碼(open file handle)。乙個開啟檔案控制代碼儲存了乙個與開啟檔案相關的全部資訊,如下所示。
當前檔案偏移量(呼叫read和write時更新,或者使用lseek直接修改)。
開啟檔案時所使用的的狀態標誌(即open的flags引數)
檔案的訪問模式(如呼叫open時所設定的唯讀模式,只寫模式或讀寫模式)
與資訊驅動io相關的設定
對該檔案i-node物件的引用。
每個檔案系統都會為駐留其上的所有檔案建立乙個i-node表。以後將詳細討論i-node結構和檔案系統的總體結構。每個檔案的i-node資訊,有以下:
檔案型別(例如,常規檔案、套接字或fifo)和訪問許可權。
乙個指標,指向該檔案所持有的鎖的列表。
檔案的各種屬性,包括檔案大小以及與不同型別操作相關的時間戳。
此處將忽略i-node在磁碟和記憶體中的表示差異。磁碟上的i-node記錄了檔案的固有屬性,諸如:檔案型別、訪問許可權和時間戳。訪問乙個檔案時,會在記憶體中為i-node建立乙個副本,其中記錄了引用該i-node的開啟檔案控制代碼數量以及i-node所在裝置的主、從裝置號,還包括一些開啟檔案時與檔案相關的臨時屬性,例如:檔案鎖。
下圖展示了檔案描述符、開啟的檔案控制代碼以及i-node之間的關係。在下圖中,兩個程序擁有諸多開啟的檔案描述符。
在程序a中,檔案描述符1和20都指向同乙個開啟的檔案控制代碼(標號為23號)。這可能是通過呼叫dup、dup2或fcntl而形成的。
程序a的檔案描述符2和程序b的檔案描述符2都指向同乙個開啟的檔案控制代碼(標號為73號)。這種情形可能在fork呼叫之後出現(即程序a和程序b是父子關係),或者當某程序通過unix套接字將乙個開啟的檔案描述符傳給另乙個程序。
此外程序a的描述符0和程序b的描述符3分別指向不同的開啟檔案的控制代碼,但這些控制代碼均指向i-node表中的相同條目(1976),換言之,指向同乙個檔案。發生這種情況是因為每個程序各自對同一檔案發起了open呼叫。同乙個程序兩次開啟同一檔案,也會發生這種情況。
結論:兩個不同的檔案描述符,若指向同乙個開啟檔案的控制代碼,將共享同一檔案偏移量。因此,如果通過其中乙個檔案描述符來修改檔案偏移量(由呼叫read、write或者lseek所致),那麼從另一檔案描述符中也會觀察到這一變化。無論這兩個檔案描述符分別屬於不同程序還是屬於同乙個程序,情況都是如此。
相比之下,檔案描述符標誌(close-on-exec)為程序和描述符所私有。這一標誌的修改不會影響同乙個程序或不同程序中的其他檔案描述符。
Unix下檔案描述符與Squid
檔案描述符是乙個簡單的整數,用以標明每乙個被程序所開啟的檔案和socket。第乙個開啟的檔案是0,第二個是1,依此類推。unix作業系統通常給每個程序能開啟的檔案數量強加乙個限制。更甚的是,unix通常有乙個系統級的限制。因為squid的工作方式,檔案描述符的限制可能會極大的影響效能。當squid用...
linux系統檔案描述符
了解個東西叫fd 檔案描述符,也就是window系統下的hwnd控制代碼。fd 是用乙個數字表示的。系統中維護了每個使用者,程序,系統級別的使用者檔案描述符數量許可權限制,即乙個程序可以開啟多少個檔案描述符,乙個使用者可以可以開啟多少個檔案描述符,乙個程序可以開啟多少個檔案描述符。以下命令可以檢視系...
CDH系統檔案描述符修改
hadoop 集群執行任務出現 too many open files 32768 我們伺服器配置的是65536並沒有生效。導致datanode服務卡住跟namenode節點通訊異常,namenode認為datanode節點已dead下線,實際datanode程序沒死,恢復正常後嘗試連線nameno...