1. 程式人生 > >文件句柄概述

文件句柄概述

擁有 必須 命令 原因 可能 種類型 end 包含 hand

Linux環境下句柄的理解
在Linux下,我們使用ulimit -n 命令可以看到單個進程能夠打開的最大文件句柄數量(socket連接也算在裏面)。系統默認值1024。
對於一般的應用來說(象Apache、系統進程)1024完全足夠使用。但是如何象squid、mysql、java等單進程處理大量請求的應用來說就有點捉襟見肘了。如果單個進程打開的文件句柄數量超過了系統定義的值,就會提到“too many files open”的錯誤提示。

備註:
Root用戶打開文件數(文件句柄數)受限於:
cat /proc/sys/fs/file-max
1405418
非root用戶打開文件數受限於:
Ulimit -n

如何知道當前進程打開了多少個文件句柄呢?

0、查看當前進程總數
lsof -nNPi | wc -l
-N指打開網絡文件
-n 不將IP轉換為hostname
-i 用以顯示符合條件的進程情況?

1、查看當前每個進程打開文件句柄數的最大的幾個進程
lsof -n |awk ‘{print $2}‘|sort|uniq -c |sort -nr|head -n 10 ???
1093 4829 #個數 進程pid
1093 26946
1093 26912

2、在系統訪問高峰時間以root用戶執行上面的腳本,可能出現的結果如下:

lsof -n|awk ‘{print $2}‘|sort|uniq -c |sort -nr|more?????

??? 131 24204???

???? 57 24244???
???? 57 24231???
???? 56 24264???
備註:其中第一行是打開的文件句柄數量,第二行是進程號。
系統限定的最大打開文件數
cat /proc/sys/fs/file-max
1405418

3、得到進程號後,我們可以通過ps命令得到進程的詳細內容。
ps -aef|grep 24204???
mysql??? 24204 24162 99 16:15 ???????? 00:24:25 /usr/sbin/mysqld???
哦,原來是mysql進程打開最多文件句柄數量。但是他目前只打開了131個文件句柄數量,遠遠底於系統默認值1024。

備註:
如果是其他程序,需要看看該程序是哪個用戶啟動,然後切換到該用戶下,
su - 用戶
Ulimit -n

Root用戶打開文件數不受ulimit -n影響

但是如果系統並發特別大,尤其是squid服務器,很有可能會超過1024。這時候就必須要調整系統參數,以適應應用變化。Linux有硬性限制和軟性限制。可以通過ulimit來設定這兩個參數。

4、方法如下,以root用戶運行以下命令:
ulimit -HSn 4096???
以上命令中,H指定了硬性大小,S指定了軟性大小,n表示設定單個進程最大的打開文件句柄數量。設定句柄數量後,系統重啟後,又會恢復默認值。如果想永久保存下來,做一下修改
tail -n 5 /etc/security/limits.conf

End of file

  • hard nofile 204800
  • soft nofile 204800

概念理解:
1.句柄就是一個標識符,只要獲得對象的句柄,我們就可以對對象進行任意的操作。
2.句柄不一定是指針。操作系統用句柄可以找到一塊內存,這個句柄可能是標識符,例如map的key,也可能是指針,看操作系統怎麽處理的了。
fd算是在某種程度上替代句柄吧;
Linux?有相應機制,但沒有統一的句柄類型,各種類型的系統資源由各自的類型來標識,由各自的接口操作。
3.在操作系統層面上,文件操作也有類似於FILE的一個概念,在Linux裏,這叫做文件描述符(File Descriptor),而在Windows裏,叫做句柄(Handle)(以下在沒有歧義的時候統稱為句柄)。用戶通過某個函數打開文件以獲得句柄,此後用戶操縱文件皆通過該句柄進行。
設計這麽一個句柄的原因在於句柄可以防止用戶隨意讀寫操作系統內核的文件對象。無論是Linux還是Windows,文件句柄總是和內核的文件對象相關聯的,但如何關聯細節用戶並不可見。內核可以通過句柄來計算出內核裏文件對象的地址,但此能力並不對用戶開放。
?
下面舉一個實際的例子,在Linux中,值為0、1、2的fd分別代表標準輸入、標準輸出和標準錯誤輸出。在程序中打開文件得到的fd從3開始增長。?fd具體是什麽呢?在內核中,每一個進程都有一個私有的“打開文件表”,這個表是一個指針數組,每一個元素都指向一個內核的打開文件對象。而fd,就是這?個表的下標。當用戶打開一個文件時,內核會在內部生成一個打開文件對象,並在這個表裏找到一個空項,讓這一項指向生成的打開文件對象,並返回這一項的下標?作為fd。由於這個表處於內核,並且用戶無法訪問到,因此用戶即使擁有fd,也無法得到打開文件對象的地址,只能夠通過系統提供的函數來操作。
?
在C語言裏,操縱文件的渠道則是FILE結構,不難想象,C語言中的FILE結構必定和fd有一對一的關系,每個FILE結構都會記錄自己唯一對應的fd。

句柄在程序設計中,句柄是一種特殊的智能指針?。當一個應用程序?要引用其他系統(如數據庫、操作系統?)所管理的內存?塊或對象?時,就要使用句柄。
句柄與普通指針?的區別在於,指針包含的是引用對象?的內存地址?,而句柄則是由系統所管理的引用標識,該標識可以被系統重新定位到一個內存地址?上。這種間接訪問對象?的模式增強了系統對引用對象?的控制。
如今,內存?容量的增大和虛擬內存?算法使得更簡單的指針?愈加受到青睞,而指向另一指針的那類句柄受到冷淡。盡管如此,許多操作系統?仍然把指向私有對象?的指針以及進程傳遞給客戶端?的內部數組?下標稱為句柄。

文件句柄概述