Linux的文件描述符

(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

1[xf@xuexi ~]$ vim a.txt 2 3[1]+ 已停止 vim a.txt 4[xf@xuexi ~]$ ps -aux | grep vim 5xf 11990 0.6 0.2 151796 5396 pts/0 T 16:37 0:00 vim a.txt 6xf 11998 0.0 0.0 112724 988 pts/0 S+ 16:37 0:00 grep --color=auto vim 7[xf@xuexi ~]$ ll /proc/11990/fd 8总用量 0 9lrwx------. 1 xf xf 64 221 16:37 0 -> /dev/pts/0 10lrwx------. 1 xf xf 64 221 16:37 1 -> /dev/pts/0 11lrwx------. 1 xf xf 64 221 16:37 2 -> /dev/pts/0 12lrwx------. 1 xf xf 64 221 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文件描述符限制有三种方式:

1[xf@xuexi ~]$ sysctl -a | grep file-max    //过滤一下,不然参数太多不好找 2sysctl: permission denied on key 'fs.protected_hardlinks' 3sysctl: permission denied on key 'fs.protected_symlinks' 4fs.file-max = 196630    //file-max其实是红色字体 5sysctl: permission denied on key 'kernel.cad_pid' 6sysctl: permission denied on key 'kernel.usermodehelper.bset' 7sysctl: permission denied on key 'kernel.usermodehelper.inheritable' 8sysctl: permission denied on key 'net.core.bpf_jit_harden' 9sysctl: permission denied on key 'net.ipv4.tcp_fastopen_key' 10sysctl: permission denied on key 'net.ipv6.conf.all.stable_secret' 11sysctl: permission denied on key 'net.ipv6.conf.default.stable_secret' 12sysctl: permission denied on key 'net.ipv6.conf.ens33.stable_secret' 13sysctl: permission denied on key 'net.ipv6.conf.lo.stable_secret' 14sysctl: permission denied on key 'net.ipv6.conf.virbr0.stable_secret' 15sysctl: permission denied on key 'net.ipv6.conf.virbr0-nic.stable_secret' 16sysctl: permission denied on key 'vm.mmap_rnd_bits' 17sysctl: permission denied on key 'vm.mmap_rnd_compat_bits' 18[xf@xuexi ~]$ cat /proc/sys/fs/file-max 19196630 20[xf@xuexi ~]$ ulimit -n 211024

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

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

1)修改用户级限制

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

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

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

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

1* hard nofile 4096 2* soft nofile 2048

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

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

2)修改系统限制级

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

  临时修改,重启后无效

1//可以使用sysctl命令修改 2[root@xuexi ~]# sysctl -w fs.file-max=8192 3fs.file-max = 8192 4[root@xuexi ~]# sysctl -a | grep fs.file-max 5fs.file-max = 8192 6sysctl: reading key "net.ipv6.conf.all.stable_secret" 7sysctl: reading key "net.ipv6.conf.default.stable_secret" 8sysctl: reading key "net.ipv6.conf.ens33.stable_secret" 9sysctl: reading key "net.ipv6.conf.lo.stable_secret" 10sysctl: reading key "net.ipv6.conf.virbr0.stable_secret" 11sysctl: reading key "net.ipv6.conf.virbr0-nic.stable_secret" 12[root@xuexi ~]# cat /proc/sys/fs/file-max 138192 14//也可以修改/proc/sys/fs/file-max文件 15[root@xuexi ~]# cat >/proc/sys/fs/file-max <<EOF 16> 16384 17> EOF 18[root@xuexi ~]# cat /proc/sys/fs/file-max 1916384 20[root@xuexi ~]# sysctl -a | grep fs.file-max 21fs.file-max = 16384 22sysctl: reading key "net.ipv6.conf.all.stable_secret" 23sysctl: reading key "net.ipv6.conf.default.stable_secret" 24sysctl: reading key "net.ipv6.conf.ens33.stable_secret" 25sysctl: reading key "net.ipv6.conf.lo.stable_secret" 26sysctl: reading key "net.ipv6.conf.virbr0.stable_secret" 27sysctl: reading key "net.ipv6.conf.virbr0-nic.stable_secret"

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

1[root@xuexi ~]# vim /etc/sysctl.conf 2[root@xuexi ~]# sysctl -a | grep fs.file-max 3fs.file-max = 196630 4sysctl: reading key "net.ipv6.conf.all.stable_secret" 5sysctl: reading key "net.ipv6.conf.default.stable_secret" 6sysctl: reading key "net.ipv6.conf.ens33.stable_secret" 7sysctl: reading key "net.ipv6.conf.lo.stable_secret" 8sysctl: reading key "net.ipv6.conf.virbr0.stable_secret" 9sysctl: reading key "net.ipv6.conf.virbr0-nic.stable_secret" 10[root@xuexi ~]# sysctl -p 11fs.file-max = 10000 12[root@xuexi ~]# sysctl -a | grep fs.file-max 13fs.file-max = 10000 14sysctl: reading key "net.ipv6.conf.all.stable_secret" 15sysctl: reading key "net.ipv6.conf.default.stable_secret" 16sysctl: reading key "net.ipv6.conf.ens33.stable_secret" 17sysctl: reading key "net.ipv6.conf.lo.stable_secret" 18sysctl: reading key "net.ipv6.conf.virbr0.stable_secret" 19sysctl: reading key "net.ipv6.conf.virbr0-nic.stable_secret"

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

点赞
收藏

评论区

加载中...

相关推荐

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

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )

IO复用-阻塞IO-非阻塞IO-同步IO-异步IO

本文是对《UNIX网络编程卷1》第6章的总结。一、            什么是IO复用?它是内核提供的一种同时监控多个文件描述符状态改变的一种能力;例如当进程需要操作多个IO相关描述符时(例如服务器程序要同时查看监听socket和大量业务socket是否有数据到来),需要内核能够监控这许多描述符,一旦这些描述符有就绪(或者状态改变了)就告