Linux的文件描述符

Stella981
• 阅读 481

(1).文件描述符的定义

  文件描述符是内核为了高效管理已被打开的文件所创建的索引,用于指向被打开的文件,所有执行I/O操作的系统调用都通过文件描述符;文件描述符是一个简单的非负整数,用以表明每个被进程打开的文件。程序刚刚启动时,第一个打开的文件是0,第二个是1,以此类推。也可以理解为文件的身份ID。

  用户通过操作系统处理信息的过程中,使用的交互设备文件(键盘,鼠标,显示器)

文件描述符

通道名

描述

默认连接

用途

0

stdin

标准输入

键盘

read only

1

stdout

标准输出

终端

write only

2

stderr

标准错误

终端

write only

3以上

filename

其他文件

none

read and/or write

标准输入输出说明

stdin,标准输入,默认设备是键盘,文件编号为0

stdout,标准输出,默认设备是显示器,文件编号为1,也可以重定向到文件

stderr,标准错误,默认设备是显示器,文件编号为2,也可以重定向到文件

(2).查看一个进程打开了哪些文件

语法: ll /proc/[进程ID]/fd

[xf@xuexi ~]$ vim a.txt 

[1]+  已停止               vim a.txt
[xf@xuexi ~]$ ps -aux | grep vim
xf        11990  0.6  0.2 151796  5396 pts/0    T    16:37   0:00 vim a.txt
xf        11998  0.0  0.0 112724   988 pts/0    S+   16:37   0:00 grep --color=auto vim
[xf@xuexi ~]$ ll /proc/11990/fd
总用量 0
lrwx------. 1 xf xf 64 2月  21 16:37 0 -> /dev/pts/0
lrwx------. 1 xf xf 64 2月  21 16:37 1 -> /dev/pts/0
lrwx------. 1 xf xf 64 2月  21 16:37 2 -> /dev/pts/0
lrwx------. 1 xf xf 64 2月  21 16:37 4 -> /home/xf/.a.txt.swp

  0、1、2也就是宏STDIN_FILENO、STDOUT_FILENO、STDERR_FILENO。

  /proc/[进程ID]/fd这个目录专门用于存放文件描述符

  另外还可以使用ls -l /proc/self/fd。

(3).文件描述符限制

  Linux中最大文件描述符的限制有两个方面,一个是用户级限制,一个是系统级限制。

  但是,查看Linux文件描述符限制有三种方式:

[xf@xuexi ~]$ sysctl -a | grep file-max    //过滤一下,不然参数太多不好找
sysctl: permission denied on key 'fs.protected_hardlinks'
sysctl: permission denied on key 'fs.protected_symlinks'
fs.file-max = 196630    //file-max其实是红色字体
sysctl: permission denied on key 'kernel.cad_pid'
sysctl: permission denied on key 'kernel.usermodehelper.bset'
sysctl: permission denied on key 'kernel.usermodehelper.inheritable'
sysctl: permission denied on key 'net.core.bpf_jit_harden'
sysctl: permission denied on key 'net.ipv4.tcp_fastopen_key'
sysctl: permission denied on key 'net.ipv6.conf.all.stable_secret'
sysctl: permission denied on key 'net.ipv6.conf.default.stable_secret'
sysctl: permission denied on key 'net.ipv6.conf.ens33.stable_secret'
sysctl: permission denied on key 'net.ipv6.conf.lo.stable_secret'
sysctl: permission denied on key 'net.ipv6.conf.virbr0.stable_secret'
sysctl: permission denied on key 'net.ipv6.conf.virbr0-nic.stable_secret'
sysctl: permission denied on key 'vm.mmap_rnd_bits'
sysctl: permission denied on key 'vm.mmap_rnd_compat_bits'
[xf@xuexi ~]$ cat /proc/sys/fs/file-max 
196630
[xf@xuexi ~]$ ulimit -n
1024

  用户级限制:ulimit命令看到的是用户级的最大文件描述符限制,也就是说每一个用户登录后执行的程序占用文件描述符的总数不能超过这个限制

  系统级限制:sysctl命令与proc文件系统中查看到的数值是一样的,这属于系统级限制,它是限制所有用户打开文件描述符的总和。

1)修改用户级限制

  临时修改上限,只对当前Shell有效

[xf@xuexi ~]$ ulimit -n  //-n打开文件描述符的最大个数
1024
[xf@xuexi ~]$ ulimit -Sn  //-S是软性限额
1024
[xf@xuexi ~]$ ulimit -Hn  //-H是硬性限额
4096
[xf@xuexi ~]$ ulimit -n 2048  //可以看到在没有指定-S和-H选项时修改会同时修改软性和硬性限额
[xf@xuexi ~]$ ulimit -n
2048
[xf@xuexi ~]$ ulimit -Sn
2048
[xf@xuexi ~]$ ulimit -Hn
2048
[xf@xuexi ~]$ ulimit -Hn 4096
bash: ulimit: open files: 无法修改 limit 值: 不允许的操作

  注意:硬性限额在设置好不能增加,除非使用root用户;软性限额可以增加,直到与硬性限额相等。

  永久修改需要使用root用户编辑/etc/security/limits.conf。里面会有详细说明。修改文件描述符,应该注意字段下是否存在nofile字段,如果存在请修改,不存在请添加。

*    hard    nofile    4096
*    soft    nofile    2048

  添加完成后保存退出,重启系统,即可生效。

  注意:soft一行中的字段要小于或等于hard一行中的字段。

2)修改系统限制级

  修改系统限制级,不管是临时修改还是永久修改都需要使用root用户。

  临时修改,重启后无效

//可以使用sysctl命令修改
[root@xuexi ~]# sysctl -w fs.file-max=8192
fs.file-max = 8192
[root@xuexi ~]# sysctl -a | grep fs.file-max
fs.file-max = 8192
sysctl: reading key "net.ipv6.conf.all.stable_secret"
sysctl: reading key "net.ipv6.conf.default.stable_secret"
sysctl: reading key "net.ipv6.conf.ens33.stable_secret"
sysctl: reading key "net.ipv6.conf.lo.stable_secret"
sysctl: reading key "net.ipv6.conf.virbr0.stable_secret"
sysctl: reading key "net.ipv6.conf.virbr0-nic.stable_secret"
[root@xuexi ~]# cat /proc/sys/fs/file-max 
8192
//也可以修改/proc/sys/fs/file-max文件
[root@xuexi ~]# cat >/proc/sys/fs/file-max <<EOF
> 16384
> EOF
[root@xuexi ~]# cat /proc/sys/fs/file-max 
16384
[root@xuexi ~]# sysctl -a | grep fs.file-max
fs.file-max = 16384
sysctl: reading key "net.ipv6.conf.all.stable_secret"
sysctl: reading key "net.ipv6.conf.default.stable_secret"
sysctl: reading key "net.ipv6.conf.ens33.stable_secret"
sysctl: reading key "net.ipv6.conf.lo.stable_secret"
sysctl: reading key "net.ipv6.conf.virbr0.stable_secret"
sysctl: reading key "net.ipv6.conf.virbr0-nic.stable_secret"

  永久修改需要进入到/etc/sysctl.conf中,修改或添加fs.file-max=value,然后重启系统或使用sysctl -p重新读取参数。

[root@xuexi ~]# vim /etc/sysctl.conf
[root@xuexi ~]# sysctl -a | grep fs.file-max
fs.file-max = 196630
sysctl: reading key "net.ipv6.conf.all.stable_secret"
sysctl: reading key "net.ipv6.conf.default.stable_secret"
sysctl: reading key "net.ipv6.conf.ens33.stable_secret"
sysctl: reading key "net.ipv6.conf.lo.stable_secret"
sysctl: reading key "net.ipv6.conf.virbr0.stable_secret"
sysctl: reading key "net.ipv6.conf.virbr0-nic.stable_secret"
[root@xuexi ~]# sysctl -p
fs.file-max = 10000
[root@xuexi ~]# sysctl -a | grep fs.file-max
fs.file-max = 10000
sysctl: reading key "net.ipv6.conf.all.stable_secret"
sysctl: reading key "net.ipv6.conf.default.stable_secret"
sysctl: reading key "net.ipv6.conf.ens33.stable_secret"
sysctl: reading key "net.ipv6.conf.lo.stable_secret"
sysctl: reading key "net.ipv6.conf.virbr0.stable_secret"
sysctl: reading key "net.ipv6.conf.virbr0-nic.stable_secret"

  注:有些人说root用户使用命令sysctl -w fs.file-max=10000,接着sysctl -p就可永久修改。可是我试下来重启系统后就会还原,有时间的可以试一下。

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Wesley13 Wesley13
2年前
IO复用-阻塞IO-非阻塞IO-同步IO-异步IO
本文是对《UNIX网络编程卷1》第6章的总结。一、            什么是IO复用?它是内核提供的一种同时监控多个文件描述符状态改变的一种能力;例如当进程需要操作多个IO相关描述符时(例如服务器程序要同时查看监听socket和大量业务socket是否有数据到来),需要内核能够监控这许多描述符,一旦这些描述符有就绪(或者状态改变了)就告
Stella981 Stella981
2年前
Linux IO 概念(1)
基础概念文件描述fd        文件描述符(filedescription),用于表述指向文件引用的抽象话题概念文件描述符在形式上是一个非负整数,实际上它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表,当程序打开一个现有文件或者创建一个新文件时,内核就向该进程返回一个文件描述符        unix系统把任何对象看做
Wesley13 Wesley13
2年前
FLV文件格式
1.        FLV文件对齐方式FLV文件以大端对齐方式存放多字节整型。如存放数字无符号16位的数字300(0x012C),那么在FLV文件中存放的顺序是:|0x01|0x2C|。如果是无符号32位数字300(0x0000012C),那么在FLV文件中的存放顺序是:|0x00|0x00|0x00|0x01|0x2C。2.  
Stella981 Stella981
2年前
Linux 文件编程、时间编程基本函数
文件编程  文件描述符fd数字(文件的身份证,代表文件身份),通过fd可找到正在操作或需要打开的文件。基本函数操作:1)打开/创建文件intopen(constcharpathname,intflag,mode_tmode)成功:返回文件的fd失败:返回
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Stella981 Stella981
2年前
Linux中的文件描述符与打开文件之间的关系
导读内核(kernel)利用文件描述符(filedescriptor)来访问文件。文件描述符是非负整数。打开现存文件或新建文件时,内核会返回一个文件描述符。读写文件也需要使用文件描述符来指定待读写的文件。1\.概述在Linux系统中一切皆可以看成是文件,文件又可分为:普通文件、目录文件、链接文件和设备文件。文件描述符(file
Wesley13 Wesley13
2年前
Java多线程导致的的一个事物性问题
业务场景我们现在有一个类似于文件上传的功能,各个子站点接受业务,业务上传文件,各个子站点的文件需要提交到总站点保存,文件是按批次提交到总站点的,也就是说,一个批次下面约有几百个文件。      考虑到白天提交这么多文件会影响到子站点其他系统带宽,我们将分站点的文件提交到总站点这个操作过程独立出来,放到晚上来做,具体时间是晚上7:00到早上7:00。