注:本文中所使用的Linux發行版爲CentOS 7 X64
一 文件描述符簡介
Linux的設計中,不僅文件是文件,還將數據也抽象成了文件,甚至將一切操作和資源抽象成了文件,比如說socket,磁盤,進程,線程等,即所謂一切皆文件。
內核爲了高效管理已被打開的文件,便創建了索引,用於指向被打開的文件。這樣,要操作文件的時候,我們直接找到索引就可以對其進行操作了,我們將這個索引叫做文件描述符(file descriptor),簡稱fd,在系統裏面是一個非負的整數。每打開或創建一個文件,內核就會向進程返回一個fd,第一個打開文件是0,第二個是1,依次遞增。在Windows系統中,與文件描述符概念對應的東西稱之爲句柄。
在實際使用中,習慣上,0、1、2,這幾個起始的文件描述符被佔坑了,即標準輸入輸出,我們在執行管道的輸出的重定向的時候經常涉及到。當然,如果你發神經,也可以將這幾個文件描述符重新定義給其他文件使用。
文件描述符 0 與 進程的標準輸入(standard input)關聯
文件描述符 1 與 標準輸出(standard output)關聯,
文件描述符 2 與 標準錯誤(standard error)關聯。
二 最大文件描述符
1 查看用戶級最大文件描述符限制
ulimit爲shell內建指令,可用來控制shell執行程序的資源。
語法
ulimit [-aHS][-c <core文件上限>][-d <數據節區大小>][-f <文件大小>][-m <內存大小>][-n <文件數目>][-p <緩衝區大小>][-s <堆疊大小>][-t <CPU時間>][-u <程序數目>][-v <虛擬內存大小>]
參數:
-a 顯示目前資源限制的設定。
-c <core文件上限> 設定core文件的最大值,單位爲區塊。
-d <數據節區大小> 程序數據節區的最大值,單位爲KB。
-f <文件大小> shell所能建立的最大文件,單位爲區塊。
-H 設定資源的硬性限制,也就是管理員所設下的限制。
-m <內存大小> 指定可使用內存的上限,單位爲KB。
-n <文件數目> 指定同一時間最多可開啓的文件數。
-p <緩衝區大小> 指定管道緩衝區的大小,單位512字節。
-s <堆疊大小> 指定堆疊的上限,單位爲KB。
-S 設定資源的彈性限制。
-t <CPU時間> 指定CPU使用時間的上限,單位爲秒。
-u <程序數目> 用戶最多可開啓的程序數目。
-v <虛擬內存大小> 指定可使用的虛擬內存上限,單位爲KB。
顯示目前資源限制的設定
ulimit -a
其中,文件描述符的限制,即open files,其限制值爲1024,即同時只能打開1024個文件,該值爲系統的默認值。
如果只是要查看文件描述符的限制,可直接使用命令:
ulimit -n
文件描述符的限制實際上分爲硬限制和軟限制,軟限制受到硬限制的約束。
ulimit -Hn:查看硬限制
ulimit -Sn:查看軟限制
2 查看系統級最大文件描述符限制
ulimit命令顯示的是用戶級的限制,要查看系統級的限制,請使用如下命令:
cat /proc/sys/fs/file-max
或者:
sysctl -a | grep file-max
系統級的限制默認值就已經非常大了。
3 查看某個進程的最大文件描述符限制
首先執行
ps-ef | grep [PName]
取得進程的PID
然後執行
cat /proc/[PID]/limits
顯示結果的Max open files一行即爲結果。
4 查看某個進程的文件描述符使用情況
首先執行
ps-ef | grep [PName]
取得進程的PID
然後執行
cd /proc/[PID]/fd
打開文件描述符目錄
執行
ls -lR | grep "^l" | wc -l
即可統計出進程當前使用的文件描述符數目。
執行
ls -al
或者
ll
即可查看進程具體打開文件情況。
5 設置文件描述符的用戶級限制
系統默認的最大文件描述符數目只有1024,很容易遇到error: too many open files。因此,我們一般會適當將其改大。
ulimit -n 65536
以上命令同時修改了最大文件描述符的軟限制和硬限制。
ulimit -n 65536等效於ulimit -HSn 65536:同時修改軟限制和硬限制。
ulimit -Hn 65536:僅修改硬限制
ulimit -Sn 65536:僅修改軟限制
以上設置僅僅當前有效,系統重啓後就無效了。要持久化配置,需修改配置文件。
vi /etc/security/limits.conf
在文件尾部增加如下內容:
root soft nofile 65535
root hard nofile 65535
* soft nofile 65535
* hard nofile 65535
修改配置後,配置在當前shell不會生效,關閉shell,重新打開shell後配置生效。
6 設置文件描述符的系統級限制
系統級的限制默認值已經非常大,一般不需要去管。
如果要修改系統級限制,請依次執行以下命令:
sysctl -w fs.file-max=758650
sysctl -p
等價於
echo 758650 > /proc/sys/fs/file-max
sysctl -p
以上設置僅僅當前有效,系統重啓後就無效了。要持久化配置,需修改配置文件:
vi /etc/sysctl.conf
添加如下內容:
fs.file-max=758650
然後執行:
sysctl -p