每一個文件描述符會與一個打開文件相對應(yīng)并蝗,同時,不同的文件描述符也會指向同一個文件秸妥。相同的文件可以被不同的進程打開也可以在同一個進程中被多次打開滚停。系統(tǒng)為每一個進程維護了一個文件描述符表,該表的值都是從0開始的粥惧,所以在不同的進程中你會看到相同的文件描述符键畴,這種情況下相同文件描述符有可能指向同一個文件,也有可能指向不同的文件。具體情況要具體分析起惕,要理解具體其概況如何涡贱,需要查看由內(nèi)核維護的3個數(shù)據(jù)結(jié)構(gòu)。
- 進程級的文件描述符表
- 系統(tǒng)級的打開文件描述符表
- 文件系統(tǒng)的i-node表
進程級的文件描述符表
進程級的描述符表的每一條目記錄了單個文件描述符的相關(guān)信息惹想。
- 控制文件描述符操作的一組標(biāo)志问词。(目前,此類標(biāo)志僅定義了一個嘀粱,即close-on-exec標(biāo)志)
- 對打開文件句柄的引用
系統(tǒng)級的描述符表格(open file description table)
內(nèi)核對所有打開的文件的文件維護有一個系統(tǒng)級的描述符表格(open file description table)激挪。有時,也稱之為打開文件表(open file table)锋叨,并將表格中各條目稱為打開文件句柄(open file handle)垄分。一個打開文件句柄存儲了與一個打開文件相關(guān)的全部信息,如下所示:
- 當(dāng)前文件偏移量(調(diào)用read()和write()時更新娃磺,或使用lseek()直接修改)
- 打開文件時所使用的狀態(tài)標(biāo)識(即薄湿,open()的flags參數(shù))
- 文件訪問模式(如調(diào)用open()時所設(shè)置的只讀模式、只寫模式或讀寫模式)
- 與信號驅(qū)動相關(guān)的設(shè)置
- 對該文件i-node對象的引用
- 文件類型(例如:常規(guī)文件豌鸡、套接字或FIFO)和訪問權(quán)限
- 一個指針嘿般,指向該文件所持有的鎖列表
- 文件的各種屬性段标,包括文件大小以及與不同類型操作相關(guān)的時間戳
下圖展示了文件描述符涯冠、打開的文件句柄以及i-node之間的關(guān)系,圖中逼庞,兩個進程擁有諸多打開的文件描述符蛇更。
在進程A中,文件描述符1和30都指向了同一個打開的文件句柄(標(biāo)號23)赛糟。這可能是通過調(diào)用dup()派任、dup2()、fcntl()或者對同一個文件多次調(diào)用了open()函數(shù)而形成的璧南。
進程A的文件描述符2和進程B的文件描述符2都指向了同一個打開的文件句柄(標(biāo)號73)掌逛。這種情形可能是在調(diào)用fork()后出現(xiàn)的(即,進程A司倚、B是父子進程關(guān)系)豆混,或者當(dāng)某進程通過UNIX域套接字將一個打開的文件描述符傳遞給另一個進程時,也會發(fā)生动知。再者是不同的進程獨自去調(diào)用open函數(shù)打開了同一個文件皿伺,此時進程內(nèi)部的描述符正好分配到與其他進程打開該文件的描述符一樣。
此外盒粮,進程A的描述符0和進程B的描述符3分別指向不同的打開文件句柄鸵鸥,但這些句柄均指向i-node表的相同條目(1976),換言之丹皱,指向同一個文件妒穴。發(fā)生這種情況是因為每個進程各自對同一個文件發(fā)起了open()調(diào)用宋税。同一個進程兩次打開同一個文件,也會發(fā)生類似情況宰翅。