注:本文中所使用的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