文件描述符fd(File Descriptor)簡介

以前看一些Linux網絡編程的文章的時候總是會遇到文件描述符fd這個東西,也沒太搞清楚。看了下面這篇文章講的還不錯,記錄下來吧。html

原文連接node

維基百科:文件描述符在形式上是一個非負整數。實際上,它是一個索引值,指向內核爲每個進程所維護的該進程打開文件的記錄表。當程序打開一個現有文件或者建立一個新文件時,內核向進程返回一個文件描述符。在程序設計中,一些涉及底層的程序編寫每每會圍繞着文件描述符展開。nginx

1、文件描述符概念

  Linux 系統中,把一切都看作是文件,當進程打開現有文件或建立新文件時,內核向進程返回一個文件描述符,文件描述符就是內核爲了高效管理已被打開的文件所建立的索引,用來指向被打開的文件,全部執行I/O操做的系統調用都會經過文件描述符。web

2、文件描述符、文件、進程間的關係

1.描述:

每一個文件描述符會與一個打開的文件相對應編程

不一樣的文件描述符也可能指向同一個文件segmentfault

相同的文件能夠被不一樣的進程打開,也能夠在同一個進程被屢次打開bash

2.系統爲維護文件描述符,創建了三個表

進程級的文件描述符表網絡

系統級的文件描述符表ui

文件系統的i-node表 (轉到:阮一峯——理解inode)spa

PS:總結一下軟硬連接。
硬連接的話,新文件和原文件的iNode號碼是同樣的。原文件的iNode的連接數會加一。刪除原文件,新文件不受影響。 軟鏈接的話,新文件和原文件的iNode號碼是不同的。原文件的iNode的連接數不變。刪除原文件,訪問新文件會報文件不存在錯誤。

3.經過這三個表,認識文件描述符

在進程A中,文件描述符1和30都指向了同一個打開的文件句柄(#23),這多是該進程屢次對執行打開操做

進程A中的文件描述符2和進程B的文件描述符2都指向了同一個打開的文件句柄(#73),這種狀況有幾種可能,1.進程A和進程B多是父子進程關係;2.進程A和進程B打開了同一個文件,且文件描述符相同(低機率事件=_=);3.A、B中某個進程經過UNIX域套接字將一個打開的文件描述符傳遞給另外一個進程。

進程A的描述符0和進程B的描述符3分別指向不一樣的打開文件句柄,但這些句柄均指向i-node表的相同條目(#1936),換言之,指向同一個文件。發生這種狀況是由於每一個進程各自對同一個文件發起了打開請求。同一個進程兩次打開同一個文件,也會發生相似狀況。

前人的思考,咱們的階梯,這部分參考自網絡:連接

3、文件描述符限制

  有資源的地方就有戰爭,「文件描述符」也是一種資源,系統中的每一個進程都須要有「文件描述符」才能進行改變世界的宏圖霸業。世界須要秩序,因而就有了「文件描述符限制」的規定。

以下表:

永久修改用戶級限制時有三種設置類型:

soft 指的是當前系統生效的設置值

hard 指的是系統中所能設定的最大值

  • 指的是同時設置了 soft 和 hard 的值

命令講解:

ulimit
複製代碼
sysctl
複製代碼

4、檢查某個進程的文件描述符相關內容 步驟(以nginx爲例,*注意權限問題,此示例是在本地環境):

找到須要檢查的進程id

如圖,找到的進程id爲 1367

查看該進程的限制

如圖,在 Max open files 那一行,能夠看到當前設置中最大文件描述符的數量爲1024

查看該進程佔用了多少個文件描述符

如圖所示,使用了17個文件描述符

總結

  實際應用過程當中,若是出現「Too many open files」 , 能夠經過增大進程可用的文件描述符數量來解決,但每每故事不會這樣結束,不少時候,並非由於進程可用的文件描述符過少,而是由於程序bug,打開了大量的文件鏈接(web鏈接也會佔用文件描述符)而沒有釋放。程序申請的資源在用完後及時釋放,纔是解決「Too many open files」的根本之道。

相關文章
相關標籤/搜索