Linux文件描述符

Linux通用I/O模型中,I/O操做系列函數(系統調用)都是圍繞一個叫作文件描述符的整數展開。這不由讓人產生疑問:這個整數表明什麼?一個數值表明一個文件嗎?隨便傳一個整數進去調用能夠嗎?html

原文地址: https://learn-linux.readthedocs.io

玩轉Linux舊羣已滿,請加新羣:278378501node

歡迎關注咱們的公衆號:小菜學編程 (coding-fan)linux

解答以上疑問,須要更深刻學習——文件描述符(File Descriptor)。shell

圖解

理解具體狀況,須要瞭解由內核維護的3個數據結構:編程

  • 進程級文件描述符表(file descriptor table)
  • 系統級打開文件表(open file table)
  • 文件系統i-node表(i-node table)

這3個數據結構之間的關係以下圖所示:微信

fd-inode-diagram.png

文件描述符表

內核爲每一個進程維護一個文件描述符表,該表每一條目都記錄了單個文件描述符的相關信息,包括:數據結構

  • 控制標誌(flags),目前內核僅定義了一個,即close-on-exec
  • 打開文件描述體指針

打開文件表

內核對全部打開的文件維護一個系統級別的打開文件描述表(open file description table),簡稱打開文件表。表中條目稱爲打開文件描述體(open file description),存儲了與一個打開文件相關的所有信息,包括:函數

  • 文件偏移量(file offset),調用read()write()更新,調用lseek()直接修改
  • 訪問模式,由open()調用設置,例如:只讀、只寫或讀寫等
  • i-node對象指針

i-node表

每一個文件系統會爲存儲於其上的全部文件(包括目錄)維護一個i-node表,單個i-node包含如下信息:學習

  • 文件類型(file type),能夠是常規文件、目錄、套接字或FIFO
  • 訪問權限
  • 文件鎖列表(file locks)
  • 文件大小
  • 等等

i-node存儲在磁盤設備上,內核在內存中維護了一個副本,這裏的i-node爲後者。副本除了原有信息,還包括:引用計數(從打開文件描述體)、所在設備號以及一些臨時屬性,例如文件鎖。spa

場景解析

上圖中,詳細描述了兩個進程諸多文件描述符,以及相互關係。

文件描述符複製

在進程A中,文件描述符1和文件描述符20都指向同一個打開文件描述體(標號23)。這極可能是經過調用dup()系列函數造成的。

文件描述符複製,在某些場景下很是有用,好比:標準輸入/輸出重定向。在shell下,完成這個操做很是簡單,大部分人都會,可是極少人思考過背後的原理。

大概描述一下須要的幾個步驟,以標準輸出(文件描述符爲1)重定向爲例:

  1. 打開目標文件,返回文件描述符n;
  2. 關閉文件描述符1;
  3. 調用dup將文件描述符n複製到1;
  4. 關閉文件描述符n;

子進程繼承文件描述符

進程A的文件描述符2和進程B的文件描述符2都指向同一個打開文件描述體(標號73)。這種情形極可能發生在調用fork()派生子進程以後,好比A調用fork()派生出B。這時,B做爲子進程,從父進程A繼承了文件描述符表,其中包括圖中標明的文件描述符2。這就是子進程繼承父進程打開的文件這句話的由來。

固然了,進程A經過Unix套接字將一個文件描述符傳遞給B也會出現相似的情形,但通常文件描述符數值是不同的。同時爲2要很是湊巧才發生。

下一步

更多文章請訪問:學習Linux

訂閱更新,獲取更多學習資料,請關注咱們的 微信公衆號 :

小菜學編程

相關文章
相關標籤/搜索