(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。里面會有詳細說明。修改文件描述符,應該注意<item>字段下是否存在nofile字段,如果存在請修改,不存在請添加。
* hard nofile 4096 * soft nofile 2048
添加完成后保存退出,重啟系統,即可生效。
注意:soft一行中的<value>字段要小於或等於hard一行中的<value>字段。
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就可永久修改。可是我試下來重啟系統后就會還原,有時間的可以試一下。
