嵌入式软件开发杂谈(2):Linux最大能创建多少文件?


曾经遇到一个问题,设备在正常运行的过程中,在打开一个文件时候,提示“Too many open files”,打开文件失败。当时一脸懵,然后检查代码,没有发现什么异常。但是在出现这个问题时候,发现进程的文件描述符数量已经占到了这个进程的被分配的最大值,但是实际上并没有这么的文件被打开使用,后续经过一些排查,发现第三方SDK在一些异常情况下创建socket之后,没有释放,频繁创建,导致此进程的文件描述符达到最大值。

特此记录下关于文件描述符的一些信息,防止遗忘。

在Linux下,万物皆为文件,因此我们在进行IO操作时候,Linux系统都会创建(open、fopen、socket等操作)对应的文件描述符,并将其写入进程对应的文件描述符表中用于维护。

系统有最大的文件描述符限制,即内核可分配的最大文件数。并且也会对每一个进程的文件描述符数量也会进行限,制防止某个进程过多占用文件资源,导致整个系统异常。

1 查看文件描述符数量

1.1 系统文件描述符最大值

即查看整个linux系统可分配的最大文件数。

方法1:使用sysctl 命令

#sysctl -a | grep fs.file-max
fs.file-max = 197295

方法2:

cat /proc/sys/fs/file-max 
197295

1.2 用户文件描述符限制值

# ulimit -n
1024

1.3 用户文件描述符可修改最大值

# cat /proc/sys/fs/nr_open                                   
1048576

上面的ulimit -n为1024,表示当前每个进程可以使用的文件数量为1024,若是对其进行修改,那么最大可修改值为1048576

1.4 查看系统使用的文件句柄数量

# cat /proc/sys/fs/file-nr 
3552	0	197295

或者使用sysctl指令

#sysctl -a | grep fs.file-nr
fs.file-nr = 3552	0	197295

如上,当前系统使用的文件句柄为3552,最大值是197295

2 修改文件描述符限制

2.1 修改系统限制

# sysctl -w fs.file-max=197296
fs.file-max = 197296
# cat /proc/sys/fs/file-max 
197296

或者可以将此值写到配置文件中,即将fs.file-max = 197296添加到/etc/sysctl.conf中去

2.2 修改用户限制

通过ulimit -n指令来进行修改,如下:

ulimit -n 4096

注意:修改单个进程可分配的最大文件也不是无限制增大的,使用如下指令可以看到linux系统对单个进程最大文件数也有限制,即1024*1024个

# cat /proc/sys/fs/nr_open                                   
1048576

如果设置超过此值,就会设置失败:

# ulimit -n 1048577                                          
/bin/sh: ulimit: 1048577 exceeds allowable nofiles(descriptors) limit

因此如果需要设置的最大值超过1024*1024,则需要先设置此值


 # echo 1048577 > /proc/sys/fs/nr_open

然后再设置单个进程最大值,即可设置成功

# ulimit -n 1048577

3 查看某个进程的使用文件数量

有时候我们需要查看某个进程的正在使用的文件数量,可以通过以下方式:

#cat /proc/950/fdinfo/                                    
0  10 12 14 16 18 2  21 23 25 27 3  4  6  8  
1  11 13 15 17 19 20 22 24 26 28 31 5  7  9

上面为全部正在使用文件,已经文件句柄值,我们也可以使用lsof指令查看:

#lsof
950	/home/test	/dev/null
950	/home/test	/dev/null
950	/home/test	/dev/null
950	/home/test	socket:[1186]
950	/home/test	/dev/xxx
950	/home/test	/dev/xxx
950	/home/test	/dev/xxx
950	/home/test	socket:[278]
950	/home/test	/dev/xxx
950	/home/test	/dev/xxx
950	/home/test	/dev/xx
950	/home/test	/etc/tet.ttf
950	/home/test	pipe:[1190]
950	/home/test	pipe:[1190]
950	/home/test	/dev/xxx
950	/home/test	an
950	/home/test	socket:[1191]
950	/home/test	/etc/font/fe.ttf
950	/home/test	/dev/ttyS2
950	/home/test	/dev/ttyS1
950	/home/test	socket:[442]
950	/home/test	/dev/xxx
950	/home/test	socket:[443]
950	/home/test	socket:[444]
950	/home/test	socket:[445]
950	/home/test	socket:[1240]
950	/home/test	socket:[1241]
950	/home/test	socket:[1242]
950	/home/test	socket:[1246]
950	/home/test	socket:[909225]
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值