程序開啟檔案的本質以及檔案描述符的本質

2021-08-27 13:44:11 字數 1238 閱讀 2140

當我們開啟檔案時,作業系統在記憶體中要建立相應的資料結構來描述目標檔案。於是就有了file結構體。表⽰⼀個已經開啟的檔案物件。而程序執行open系統調⽤,所以必須讓程序和檔案關聯起來。每個程序都有⼀個指標*files, 指向⼀張表files_struct,該錶最重要的部分就是包涵乙個指標陣列,每個元素都是乙個指向開啟檔案的指標!所以,本質上,檔案描述符就是該陣列的下標。所以,只要拿著檔案描述符,就可以找到對應的檔案。

本質是陣列元素的下標,每個程序都對應一張檔案描述符表,該錶可視為指標陣列,給陣列的元素指向檔案表的乙個元素,陣列元素的下標就是大名鼎鼎的檔案描述符

圖詳解:

1.右側的表稱為i節點表,在整個系統中只有1張。該錶可以視為結構體陣列,該陣列的乙個元素對應於乙個物理檔案。

2.中間的表稱為檔案表,在整個系統中只有1張。該錶可以視為結構體陣列,乙個結構體中有很多字段,其中有3個字段比較重要:

file status flags

用於記錄檔案被開啟來讀的,還是寫的。其實記錄的就是open呼叫中使用者指定的第2個引數

current file offset

用於記錄檔案的當前讀寫位置(指標)。正是由於此字段的存在,使得乙個檔案被開啟並讀取後,

下一次讀取將從上一次讀取的字元後開始讀取

v-node ptr

該字段是指標,指向右側表的乙個元素,從而關聯了物理檔案。

3.左側的表稱為檔案描述符表,每個程序有且僅有1張。該錶可以視為指標陣列,陣列的元素指向檔案表的乙個元素。最重要的是:陣列元素的下標就是大名鼎鼎的檔案描述符。

4.open系統呼叫執行的操作:新建乙個i節點表元素,讓其對應開啟的物理檔案(如果對應於該物理檔案的i節點元素已經建立,就不做任何操作);新建乙個檔案表的元素,根據open的第2個引數設定file status flags欄位,將current file offset欄位置0,將v-node ptr指向剛建立的i節點表元素;在檔案描述符表中,尋找1個尚未使用的元素,在該元素中填入乙個指標值,讓其指向剛建立的檔案表元素。最重要的是:將該元素的下標作為open的返回值返回。

5.這樣一來,當呼叫read(write)時,根據傳入的檔案描述符,os就可以找到對應的檔案描述符表元素,進而找到檔案表的元素,進而找到i節點表元素,從而完成對物理檔案的讀寫。

fork 子程序不繼承父程序開啟的檔案描述符

昨天面試被問到了這個問題,沒有回答上來,網上找了一下答案。解決方法是使用clone系統呼叫使用引數在複製時將父程序資源有選擇地複製給子程序。下面介紹forkvforkclone三者的區別 vfork系統呼叫不同於fork,用vfork建立的子程序與父程序共享位址空間,也就是說子程序完全執行在父程序的...

程序最大開啟檔案描述符個數

不過在看下節之前,首先知道在本機下開啟的檔案描述符個數的個數不能超過1024,除去3個輸入輸出還有epoll的檔案描述符,所以程式傳入的最大開啟檔案描述符的引數不能超過1020.如果超過服務端報錯結果如下 通過檢視乙個程序的最多開啟個數,ulimit n設定臨時設定開啟個數 limit n10001...

檔案描述符以及動態檔案

檔案描述符 1.對於核心而言,所有的開啟檔案都由檔案描述符引用,檔案描述符是乙個非負整數,當開啟乙個現存盤案或者建立乙個新檔案時,核心向程序返回乙個檔案描述符。當讀寫乙個檔案時,用open和creat返回為的檔案描述符標識該檔案,將其作為引數傳遞給read和write.按照慣例,unix shell...