日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > linux >内容正文

linux

linux c中的文件描述符与打开文件之间的关系

發(fā)布時(shí)間:2023/12/4 linux 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux c中的文件描述符与打开文件之间的关系 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

轉(zhuǎn)載請(qǐng)說(shuō)明出處:http://blog.csdn.net/cywosp/article/details/38965239


1. 概述 ? ? 在Linux系統(tǒng)中一切皆可以看成是文件,文件又可分為:普通文件、目錄文件、鏈接文件和設(shè)備文件。文件描述符(file descriptor)是內(nèi)核為了高效管理已被打開(kāi)的文件所創(chuàng)建的索引,其是一個(gè)非負(fù)整數(shù)(通常是小整數(shù)),用于指代被打開(kāi)的文件,所有執(zhí)行I/O操作的系統(tǒng)調(diào)用都通過(guò)文件描述符。程序剛剛啟動(dòng)的時(shí)候,0是標(biāo)準(zhǔn)輸入,1是標(biāo)準(zhǔn)輸出,2是標(biāo)準(zhǔn)錯(cuò)誤。如果此時(shí)去打開(kāi)一個(gè)新的文件,它的文件描述符會(huì)是3。POSIX標(biāo)準(zhǔn)要求每次打開(kāi)文件時(shí)(含socket)必須使用當(dāng)前進(jìn)程中最小可用的文件描述符號(hào)碼,因此,在網(wǎng)絡(luò)通信過(guò)程中稍不注意就有可能造成串話。標(biāo)準(zhǔn)文件描述符圖如下:
文件描述與打開(kāi)的文件對(duì)應(yīng)模型如下圖:
2. 文件描述限制 ? ? 在編寫(xiě)文件操作的或者網(wǎng)絡(luò)通信的軟件時(shí),初學(xué)者一般可能會(huì)遇到“Too many open files”的問(wèn)題。這主要是因?yàn)槲募枋龇窍到y(tǒng)的一個(gè)重要資源,雖然說(shuō)系統(tǒng)內(nèi)存有多少就可以打開(kāi)多少的文件描述符,但是在實(shí)際實(shí)現(xiàn)過(guò)程中內(nèi)核是會(huì)做相應(yīng)的處理的,一般最大打開(kāi)文件數(shù)會(huì)是系統(tǒng)內(nèi)存的10%(以KB來(lái)計(jì)算)(稱之為系統(tǒng)級(jí)限制),查看系統(tǒng)級(jí)別的最大打開(kāi)文件數(shù)可以使用sysctl -a | grep fs.file-max命令查看。與此同時(shí),內(nèi)核為了不讓某一個(gè)進(jìn)程消耗掉所有的文件資源,其也會(huì)對(duì)單個(gè)進(jìn)程最大打開(kāi)文件數(shù)做默認(rèn)值處理(稱之為用戶級(jí)限制),默認(rèn)值一般是1024,使用ulimit -n命令可以查看。在Web服務(wù)器中,通過(guò)更改系統(tǒng)默認(rèn)值文件描述符的最大值來(lái)優(yōu)化服務(wù)器是最常見(jiàn)的方式之一,具體優(yōu)化方式請(qǐng)查看http://blog.csdn.net/kumu_linux/article/details/7877770。
3. 文件描述符合打開(kāi)文件之間的關(guān)系 ? ? 每一個(gè)文件描述符會(huì)與一個(gè)打開(kāi)文件相對(duì)應(yīng),同時(shí),不同的文件描述符也會(huì)指向同一個(gè)文件。相同的文件可以被不同的進(jìn)程打開(kāi)也可以在同一個(gè)進(jìn)程中被多次打開(kāi)。系統(tǒng)為每一個(gè)進(jìn)程維護(hù)了一個(gè)文件描述符表,該表的值都是從0開(kāi)始的,所以在不同的進(jìn)程中你會(huì)看到相同的文件描述符,這種情況下相同文件描述符有可能指向同一個(gè)文件,也有可能指向不同的文件。具體情況要具體分析,要理解具體其概況如何,需要查看由內(nèi)核維護(hù)的3個(gè)數(shù)據(jù)結(jié)構(gòu)。 ? ? 1. 進(jìn)程級(jí)的文件描述符表 ? ? 2. 系統(tǒng)級(jí)的打開(kāi)文件描述符表 ? ? 3. 文件系統(tǒng)的i-node表
進(jìn)程級(jí)的描述符表的每一條目記錄了單個(gè)文件描述符的相關(guān)信息。 ? ? 1. 控制文件描述符操作的一組標(biāo)志。(目前,此類標(biāo)志僅定義了一個(gè),即close-on-exec標(biāo)志) ? ? 2. 對(duì)打開(kāi)文件句柄的引用
內(nèi)核對(duì)所有打開(kāi)的文件的文件維護(hù)有一個(gè)系統(tǒng)級(jí)的描述符表格(open file description table)。有時(shí),也稱之為打開(kāi)文件表(open file table),并將表格中各條目稱為打開(kāi)文件句柄(open file handle)。一個(gè)打開(kāi)文件句柄存儲(chǔ)了與一個(gè)打開(kāi)文件相關(guān)的全部信息,如下所示: ? ? 1. 當(dāng)前文件偏移量(調(diào)用read()和write()時(shí)更新,或使用lseek()直接修改) ? ? 2. 打開(kāi)文件時(shí)所使用的狀態(tài)標(biāo)識(shí)(即,open()的flags參數(shù)) ? ? 3. 文件訪問(wèn)模式(如調(diào)用open()時(shí)所設(shè)置的只讀模式、只寫(xiě)模式或讀寫(xiě)模式) ? ? 4. 與信號(hào)驅(qū)動(dòng)相關(guān)的設(shè)置 ? ? 5. 對(duì)該文件i-node對(duì)象的引用 ? ? 6. 文件類型(例如:常規(guī)文件、套接字或FIFO)和訪問(wèn)權(quán)限 ? ? 7. 一個(gè)指針,指向該文件所持有的鎖列表 ? ? 8. 文件的各種屬性,包括文件大小以及與不同類型操作相關(guān)的時(shí)間戳
下圖展示了文件描述符、打開(kāi)的文件句柄以及i-node之間的關(guān)系,圖中,兩個(gè)進(jìn)程擁有諸多打開(kāi)的文件描述符。 ? ? 在進(jìn)程A中,文件描述符1和30都指向了同一個(gè)打開(kāi)的文件句柄(標(biāo)號(hào)23)。這可能是通過(guò)調(diào)用dup()、dup2()、fcntl()或者對(duì)同一個(gè)文件多次調(diào)用了open()函數(shù)而形成的。 ? ? 進(jìn)程A的文件描述符2和進(jìn)程B的文件描述符2都指向了同一個(gè)打開(kāi)的文件句柄(標(biāo)號(hào)73)。這種情形可能是在調(diào)用fork()后出現(xiàn)的(即,進(jìn)程A、B是父子進(jìn)程關(guān)系),或者當(dāng)某進(jìn)程通過(guò)UNIX域套接字將一個(gè)打開(kāi)的文件描述符傳遞給另一個(gè)進(jìn)程時(shí),也會(huì)發(fā)生。再者是不同的進(jìn)程獨(dú)自去調(diào)用open函數(shù)打開(kāi)了同一個(gè)文件,此時(shí)進(jìn)程內(nèi)部的描述符正好分配到與其他進(jìn)程打開(kāi)該文件的描述符一樣。 ? ? 此外,進(jìn)程A的描述符0和進(jìn)程B的描述符3分別指向不同的打開(kāi)文件句柄,但這些句柄均指向i-node表的相同條目(1976),換言之,指向同一個(gè)文件。發(fā)生這種情況是因?yàn)槊總€(gè)進(jìn)程各自對(duì)同一個(gè)文件發(fā)起了open()調(diào)用。同一個(gè)進(jìn)程兩次打開(kāi)同一個(gè)文件,也會(huì)發(fā)生類似情況。
4. 總結(jié) ? ??1. 由于進(jìn)程級(jí)文件描述符表的存在,不同的進(jìn)程中會(huì)出現(xiàn)相同的文件描述符,它們可能指向同一個(gè)文件,也可能指向不同的文件 ? ? 2. 兩個(gè)不同的文件描述符,若指向同一個(gè)打開(kāi)文件句柄,將共享同一文件偏移量。因此,如果通過(guò)其中一個(gè)文件描述符來(lái)修改文件偏移量(由調(diào)用read()、write()或lseek()所致),那么從另一個(gè)描述符中也會(huì)觀察到變化,無(wú)論這兩個(gè)文件描述符是否屬于不同進(jìn)程,還是同一個(gè)進(jìn)程,情況都是如此。 ? ? 3. 要獲取和修改打開(kāi)的文件標(biāo)志(例如:O_APPEND、O_NONBLOCK和O_ASYNC),可執(zhí)行fcntl()的F_GETFL和F_SETFL操作,其對(duì)作用域的約束與上一條頗為類似。 ? ? 4. 文件描述符標(biāo)志(即,close-on-exec)為進(jìn)程和文件描述符所私有。對(duì)這一標(biāo)志的修改將不會(huì)影響同一進(jìn)程或不同進(jìn)程中的其他文件描述符





參考 [1]?http://blog.chinaunix.net/uid-20633888-id-2747146.html [2]?http://www.cppblog.com/guojingjia2006/archive/2012/11/21/195450.html [3]?http://blog.csdn.net/kumu_linux/article/details/7877770 [4] 《Linux/UNIX系統(tǒng)編程手冊(cè)》

總結(jié)

以上是生活随笔為你收集整理的linux c中的文件描述符与打开文件之间的关系的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。