ulimit命令查看和更改系统限制
ulimit命令详解
ulimit用于shell启动进程所占用的资源,可以用来设置系统的限制;
语法格式:ulimit [-acdfHlmnpsStvw] [size]
在/etc/security/limits.conf
文件中定义
可以使用ulimit -a查看系统的所有限制
Linux大部分的命令设置都是临时生效的,而且ulimit命令只对当前终端有效。
如果需要永久有效的话,可以:
- 一种是将命令写至profile和bashrc中,相当于在登陆时自动动态修改限制;
- 还有一种就是在/etc/security/limits.conf中添加记录(需重启生效,并且在/etc/pam.d/中的seesion有使用到limit模块);
最大进程数目
Linux中进程的理论最大数计算
每个进程都要在全局段描述表GDT中占据两个表项。
每个进程的局部段描述表LDT都作为一个独立的段而存在,在全局段描述表GDT中要有一个表项指向这个段的起始地址,并说明该段的长度以及其他一些 参数。除上之外,每个进程还有一个TSS结构(任务状态段)也是一样。所以,每个进程都要在全局段描述表GDT中占据两个表项。
GDT的容量有多大呢?
段寄存器中用作GDT表下标的位段宽为13位,所以GDT中可以有2^13 = 8192个描述符;
除一些系统的开销(例如GDT中的第2项和第3项分别用于内核 的代码段和数据段,第4项和第5项永远用于当前进程的代码段和数据段,第1项永远是0,等等)以外,尚有8180个表项可供使用,所以理论上系统中最大的 进程数量是8180/2=4090。
所以系统中理论上最大的进程数是4090。
系统中可创建的进程数实际值
Linux内核通过进程标识符(process identification value)—PID来标识进程,PID是一个整数,类型为pid_t,实际上就是int类型。
为了与老版本的Unix或Linux兼容,PID最大值默认是32768(short int短整型最大值)。
- 查看
可以使用cat /proc/sys/kernel/pid_max
来查看系统中可创建的进程数实际值 - 修改
ulimit -u 65535
设置完之后,虽然我们设置创建进程数的硬限制和软限制都是65535,但还是不能创建65535个进程,需要在Linux设置内核参数kernel.pid_max,这个参数默认安装都是32768,所以即便是root用户,却不设置这个内核参数,整个系统最多可创建进程数就是32768,所以,需进行如下设置:
sysctl -w kernel.pid_max=65535
最大线程数
Linux系统中单个进程的最大线程数有其最大限制:PTHREAD_THREADS_MAX
这个限制可以在/usr/include/bits/local_lim.h
中查看,对linuxthreads这个值一般是1024,对于nptl没有硬性的限制,仅仅受限于系统的资源,系统的资源主要就是线程的stack所占用的内存,用ulimit -s可以查看默认的线程栈的大小,一般情况下,这个值是8M = 8192KB。
Linux中单个进程理论上可以创建的最大线程数
在我们的系统(Ubuntu-14.04-LTS-64bit)中linuxthreads 上最多可以创建 381 个线程,之后就会返回 EAGAIN,而32为系统中,可以创建381个线程,这个值和理论完全符合,因为32位Linux下的用户进程空间是3G大小,也就是3072M,3072 / 8 = 384,但是实际上代码段和数据段还要占用一些空间,这个值应该向下取整到383,再减去主线程,得到382,那么为什么linuxthreads上还要少一个线程呢?因为linuxthreads还需要一个 管理线程。
为了突破内存的额限制,可以有两种方法:
- 用
ulimit -s 1024
减小默认的栈大小; - 调用pthread_create的时候用pthread_attr_getstacksize设置一个较小的栈大小;
要注意,即使这样的也无法突破1024个线程的硬限制,除非重新编译C库。
最大打开文件数
file-max系统最大打开文件描述符数
/proc/sys/fs/file-max
中指定了系统范围内所有进程可打开的文件句柄的数量限制(系统级别, kernel-level)。
The value in file-max denotes the maximum number of file handles that the Linux kernel will allocate).
当收到”Too many open files in system”这样的错误消息时, 就应该增加这个值了。
对于2.2的内核, 还需要考虑inode-max, 一般inode-max设置为file-max的4倍. 对于2.4及以后的内核, 没有inode-max这个文件了。
查看实际值
可以使用cat /proc/sys/fs/file-max
来查看当前系统中单进程可打开的文件描述符数目
设置
- 临时性设置:
echo 1000000 > /proc/sys/fs/file-max
; - 永久性设置:在
/etc/sysctl.conf
中设置fs.file-max = 1000000
;
nr_open是单个进程可分配的最大文件数
内核支持的最大file handle数量,即一个进程最多使用的file handle数
A process cannot use more than NR_OPEN file descriptors.
一个进程不能使用超过NR_OPEN文件描述符
nofile进程最大打开文件描述符数
ulimit -n
默认查看的是软资源限制值soft limit,如果想要查看系统硬件所能支持的单进程最大打开文件描述符号的数目,可以使用ulimit -Hn
设置
- 临时性:
通过ulimit -Sn设置最大打开文件描述符数的soft limit,注意soft limit不能大于hard limit(ulimit -Hn可查看hard limit);
另外ulimit -n默认查看的是soft limit,但是ulimit -n 1800000则是同时设置soft limit和hard limit;
对于非root用户只能设置比原来小的hard limit;
- 永久性:
上面的方法只是临时性的,注销重新登录就失效了,而且不能增大hard limit,只能在hard limit范围内修改soft limit;
若要使修改永久有效,则需要在/etc/security/limits.conf中进行设置(需要root权限),可添加如下两行,表示用户chanon最大打开文件描述符数的soft limit为1800000,hard limit为2000000。以下设置需要注销之后重新登录才能生效:
chanon soft nofile 102400
chanon hard nofile 409600
设置nofile的hard limit还有一点要注意的就是hard limit不能大于/proc/sys/fs/nr_open,假如hard limit大于nr_open,注销后无法正常登录。
file-max是内核可分配的最大文件数,nr_open是单个进程可分配的最大文件数,所以在我们使用ulimit或limits.conf来设置时,如果要超过默认的1048576值时需要先增大nr_open值(sysctl -w fs.nr_open=100000000或者直接写入sysctl.conf文件)。
- 所有进程打开的文件描述符数不能超过/proc/sys/fs/file-max;
- 单个进程打开的文件描述符数不能超过user limit中nofile的soft limit;
- nofile的soft limit不能超过其hard limit;
- nofile的hard limit不能超过/proc/sys/fs/nr_open(单个进程可分配的最大文件数);