写在前面,linux的描述符有进程描述符、文件描述符、内存描述符。首先标题想了很久linux的描述符从哪里说起,看了几份资料后还是决定从进程描述符说起。但是此文章还是重点说的是文件描述符。知识深度有限,如有错误,请指出。
进程描述符:linux为了管理进程,内核必须对每个进程所作的事情进行清楚的描述,例如内核必须知道进程的优先级,它是正在cpu上运行还是因某事而被堵塞?给它分配了什么样的地址空间(内存描述符),可访问哪些文件(文件描述符),进程描述符存放很多信息,如下图:
files_struct 如下图:
从上图可得:
task_struct -----> file_struct(fd) -----> find opened file list -----> 被打开文件的信息(dentry) -----> 文件本身信息(inode) -----> 磁盘
文件描述符fd:
文件描述符是linux内核为了高效管理已被打开的文件所创建的索引,所有的IO操作系统调用都是使用文件描述符。
每打开一个文件都会创建文件描述符,并将文件指针指向这个文件描述符,文件描述符由非负整数表示,系统默认的3个文件描述符是0,1,2,即标准输入、标准输出、标准错误输出。
此时打开一个文件即从3开始,写入到文件描述符表中。每个进程在PCB(Process Control Block)即进程控制块中都保存着一份文件描述符表。
能打开多少文件描述符?理论来说内存有多大就可以打开多少文件描述符,但内核进行管理 一般是内存的10%(系统限制)。
查看系统限制可以创建多少文件描述符:
方法1. [root@WebA-136 ~]# sysctl -a | grep fs.file-max fs.file-max = 98622 方法2. [root@WebA-136 ~]# cat /proc/sys/fs/file-max 98622 [root@WebA-136 ~]#
内核为了不让某个进程消耗掉所有文件资源,会对单个进程最大打开文件个数做限制:
查看用户级别的使用ulimit
[root@WebA-136 ~]# ulimit -n#列出每个进程可以打开的文件数,此值不能超过1024*1024,内核限制,若要超过此值需要重新编译内核。从内核2.6.25可以动态修改此值vim /proc/sys/fs/nr_open 1024 [root@Management-Machine-140 ~]# cat /proc/sys/fs/nr_open 1048576 [root@Management-Machine-140 ~]# ulimit -n 1048577 -bash: ulimit: open files: cannot modify limit: Operation not permitted [root@Management-Machine-140 ~]# echo '1048577' > /proc/sys/fs/nr_open [root@Management-Machine-140 ~]# cat /proc/sys/fs/nr_open 1048577 [root@Management-Machine-140 ~]# ulimit -n 1048577
修改系统限制
临时修改 [root@WebA-136 ~]# sysctl -w fs.file-max=400000 fs.file-max = 400000 You have new mail in /var/spool/mail/root [root@WebA-136 ~]# echo 350000 >/proc/sys/fs/file-max [root@WebA-136 ~]# sysctl -a | grep fs.file-max fs.file-max = 350000 [root@WebA-136 ~]# 永久修改 将fs.file-max=400000添加到/etc/sysctl.conf配置文件中。
ulimit命令:限制进程对系统资源的使用情况。常用限制有:
内核文件大小限制
进程数据块大小限制
shell进程创建文件大小限制
可加锁内存大小限制
常驻内存集大小限制
打开文件描述符数量限制
分配堆栈的最大大小限制
cpu占用时间限制用户最大可用的进程数限制
shell进程所能使用的最大虚拟内存限制
常用选项:
-a 显示当前系统所有的limit资源信息
-H 设置硬资源限制,一旦设置不能增加
-S 设置软资源限制,设置后可以增加,但是不能超过硬资源设置
-c 最大的core文件的大小,以 blocks 为单位
-f 进程可以创建文件的最大值,以blocks 为单位
-d 进程最大的数据段的大小,以Kbytes 为单位
-m 最大内存大小,以Kbytes为单位
-n 可以打开的最大文件描述符的数量
-p 管道缓冲区的大小,以Kbytes 为单位
-s 线程栈大小,以Kbytes为单位
-u 用户最大可用的进程数
-v 进程最大可用的虚拟内存,以Kbytes 为单位
-t 最大CPU占用时间,以秒为单位
-l 最大可加锁内存大小,以Kbytes 为单位
修改用户级别
临时修改,重启失效 [root@WebA-136 ~]# ulimit -SHn 10240#修改可以打开的文件描述符数量限制 [root@WebA-136 ~]# ulimit -n 10240 永久修改,所有用户都生效。将hard,soft写入文件中,此文件格式是#<domain>用户或@组名或* <type>限制类型hard soft <item>限制的资源名称 <value> 值 [root@WebA-136 ~]# vim /etc/security/limits.conf 永久修改,所有用户都生效。在/etc/security/limits.d/90-nproc.conf 中,系统会先读取这个文件,此文件中的项目会覆盖/etc/security/limits.conf中的项目,建议将其一内容注释。 永久修改,修改单一用户,写入用户环境变量中 .bash_profile 写入ulimit -SHn 10240. [root@Management-Machine-140 ~]# echo "ulimit -SHn 10240" >>/root/.bash_profile [root@Management-Machine-140 ~]# ulimit -n #已修改 10240 [root@Management-Machine-140 ~]# 或者在应用程序的启动脚本写入ulimit -n 10240
ulimit -a显示当前用户所有系统限制
[root@Management-Machine-140 ~]# ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 7802 max locked memory (kbytes, -l) 64 max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 10240 cpu time (seconds, -t) unlimited max user processes (-u) 7802 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited [root@Management-Machine-140 ~]#
ulimit -SHn 修改硬限制、软限制和文件描述符数
[root@Management-Machine-140 ~]# ulimit -SHn 11223 [root@Management-Machine-140 ~]# ulimit -n 11223 [root@Management-Machine-140 ~]# . /root/.bash_profile#我这里已经对当前用户所有进程都设置打开文件描述符数为10240了 [root@Management-Machine-140 ~]# ulimit -n 10240 [root@Management-Machine-140 ~]#
查看用户可以创建的进程数量限制
[root@Management-Machine-140 ~]# ulimit -u 7802 [root@Management-Machine-140 ~]#
查看所有用户创建的进程数量
[root@Management-Machine-140 ~]# ps h -Led -o user | sort | uniq -c | sort -n 2 dbus 2 postfix 193 root
注:ulimit 生效后,若是web服务器。需要重启web服务。