POSIX標準要求每次打開文件時(含socket)必須使用當前進程中最小可用的文件描述符號碼
1. 當前文件偏移量(調用read()和write()時更新,或使用lseek()直接修改)
2. 打開文件時所使用的狀態標識(即,open()的flags參數)
3. 文件訪問模式(如調用open()時所設置的只讀模式、只寫模式或讀寫模式)
4. 與信號驅動相關的設置
5. 對該文件i-node對象的引用
6. 文件類型(例如:常規文件、套接字或FIFO)和訪問權限
7. 一個指針,指向該文件所持有的鎖列表
8. 文件的各種屬性,包括文件大小以及與不同類型操作相關的時間戳
在進程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()調用。同一個進程兩次打開同一個文件,也會發生類似情況。
7. 總結
1. 由於進程級文件描述符表的存在,不同的進程中會出現相同的文件描述符,它們可能指向同一個文件,也可能指向不同的文件
2. 兩個不同的文件描述符,若指向同一個打開文件句柄,將共享同一文件偏移量。因此,如果通過其中一個文件描述符來修改文件偏移量(由調用read()、write()或lseek()所致),那麼從另一個描述符中也會觀察到變化,無論這兩個文件描述符是否屬於不同進程,還是同一個進程,情況都是如此。
3. 要獲取和修改打開的文件標誌(例如:O_APPEND、O_NONBLOCK和O_ASYNC),可執行fcntl()的F_GETFL和F_SETFL操作,其對作用域的約束與上一條頗為類似。
4. 文件描述符標誌(即,close-on-exec)為進程和文件描述符所私有。對這一標誌的修改將不會影響同一進程或不同進程中的其他文件描述符
喜歡我的文章的話,就關注我吧!不要只收藏和轉發哦,每天至少兩篇編程知識給大家,都是本人多年的經驗總結!
閱讀更多 cpp軟件架構獅 的文章