在Linux通用I/O模型中,I/O
操做系列函數(系統調用)都是圍繞一個叫作文件描述符的整數展開。這不由讓人產生疑問:這個整數表明什麼?一個數值表明一個文件嗎?隨便傳一個整數進去調用能夠嗎?html
原文地址: https://learn-linux.readthedocs.io 。玩轉Linux舊羣已滿,請加新羣:278378501 。node
歡迎關注咱們的公衆號:小菜學編程 (coding-fan)linux
解答以上疑問,須要更深刻學習——文件描述符(File Descriptor)。shell
理解具體狀況,須要瞭解由內核維護的3個數據結構:編程
這3個數據結構之間的關係以下圖所示:微信
內核爲每一個進程維護一個文件描述符表,該表每一條目都記錄了單個文件描述符的相關信息,包括:數據結構
close-on-exec
內核對全部打開的文件維護一個系統級別的打開文件描述表(open file description table),簡稱打開文件表。表中條目稱爲打開文件描述體(open file description),存儲了與一個打開文件相關的所有信息,包括:函數
read()
和write()
更新,調用lseek()
直接修改open()
調用設置,例如:只讀、只寫或讀寫等i-node
對象指針每一個文件系統會爲存儲於其上的全部文件(包括目錄)維護一個i-node
表,單個i-node
包含如下信息:學習
FIFO
i-node
存儲在磁盤設備上,內核在內存中維護了一個副本,這裏的i-node
表爲後者。副本除了原有信息,還包括:引用計數(從打開文件描述體)、所在設備號以及一些臨時屬性,例如文件鎖。spa
上圖中,詳細描述了兩個進程諸多文件描述符,以及相互關係。
在進程A
中,文件描述符1和文件描述符20都指向同一個打開文件描述體(標號23)。這極可能是經過調用dup()
系列函數造成的。
文件描述符複製,在某些場景下很是有用,好比:標準輸入/輸出重定向。在shell
下,完成這個操做很是簡單,大部分人都會,可是極少人思考過背後的原理。
大概描述一下須要的幾個步驟,以標準輸出(文件描述符爲1)重定向爲例:
dup
將文件描述符n複製到1;進程A
的文件描述符2和進程B
的文件描述符2都指向同一個打開文件描述體(標號73)。這種情形極可能發生在調用fork()
派生子進程以後,好比A
調用fork()
派生出B
。這時,B
做爲子進程,從父進程A
繼承了文件描述符表,其中包括圖中標明的文件描述符2。這就是子進程繼承父進程打開的文件
這句話的由來。
固然了,進程A
經過Unix
套接字將一個文件描述符傳遞給B
也會出現相似的情形,但通常文件描述符數值是不同的。同時爲2要很是湊巧才發生。
更多文章請訪問:學習Linux
訂閱更新,獲取更多學習資料,請關注咱們的 微信公衆號 :