一、概念
1.1 文件描述符&文件描述符表
文件描述符(file descriptor, fd)是Linux系统中对已打开文件的一个抽象标记,所有I/O系统调用对已打开文件的操作都要用到它。这里的“文件”仍然是广义的,即除了普通文件和目录外,还包括管道、FIFO(命名管道)、Socket、终端、设备等
文件描述符是一个较小的非负整数,并且0、1、2三个描述符总是默认分配给标准输入、标准输出和标准错误(即常用的 nohup test.sh > test.log 2>&1
表中每个条目包含两个域:
- 控制该描述符的标记域(flags)
- 指向系统级别的打开文件表中对应条目的指针
1.2 文件句柄&打开文件表
内核会维护系统内所有打开的文件及其相关的元信息,该结构称为打开文件表(open file table)。表中每个条目包含以下域:
- 文件的偏移量。POSIX API中的read()/write()/lseek()函数都会修改该值
- 打开文件时的状态和权限标记。通过open()函数的参数传入
- 文件的访问模式(只读、只写、读+写等)通过open()函数的参数传入
- 指向其对应的inode对象的指针
1.3 文件描述符表,打开文件表,inode表之间的关系
数字代表下标,不表示标准描述符
可见,一个打开的文件可以对应多个文件描述符(不管是同进程还是不同进程),一个inode也可以对应多个打开的文件
打开文件表中的一行称为一条文件描述(file description),也经常称为文件句柄(file handle)
二、文件描述符与文件句柄的限制
例如系统报错 too many open files
2.1 文件描述符
2.1.1 查看
#查看进程的文件描述符
ll /proc/PID/fd
lsof
#查看进程级别最大文件描述符数
ulimit -n
#查看用户级别最大文件描述符数
ulimit -u
#查看当前使用的文件描述符数
lsof -P -n | wc -l
2.1.2 修改
临时修改
ulimit -Sn
ulimit -Hn
永久修改(重启后生效)
vim /etc/security/limits.conf
#OPPO Standard limits config
root hard nofile unlimited #root用户最大描述符使用数量--无限
* soft nofile 20480000 #*表示所有用户,超过发出警告
* hard nofile 20480000 #最大描述符使用数量,超过输出错误
2.2 文件句柄
2.2.1 查看
#查看最大文件句柄打开数
cat /proc/sys/fs/file-max
#三列数据分别为:已分配文件句柄的数目,已分配未使用文件句柄的数目,文件句柄的最大数目
cat /proc/sys/fs/file-nr
2.2.2 修改
临时修改
echo 6553500 > /proc/sys/fs/file-max
永久修改(使用sysctl -p 即不需要重启系统也可以生效)
echo "fs.file-max=419430" >> /etc/sysctl.conf
sysctl -p