概述
在实际工作中会经常遇到一些bug,有些就需要用到文件句柄,文件描述符等概念,比如报错: too many open files, 如果你对相关知识一无所知,那么debug起来将会异常痛苦。在linux操作系统中,文件句柄(包括Socket句柄)、打开文件、文件指针、文件描述符的概念比较绕,而且windows的文件句柄又与此有何关联和区别?这一系列的问题是我们不得不面对的。
笔者通过翻阅相关资料,并采用了一些demo来验证相关观点。如果文中有理解偏差,欢迎指正。
这里先笼统的将一下笔者对上面的问题的一些理解:
句柄,熟悉Windows编程的人知道,句柄是Windows用来标识被应用程序所建立或使用的对象的唯一整数,windows使用各种各样的句柄标识诸如应用程序实例、窗口、控制、位图等。Windows的句柄有点像C语言中的文件句柄。更通俗的理解,句柄是一种指向指针的指针。
在linux系统中文件句柄(file handles)和文件描述符(file descriptor)是一个一一对应的关系(如果错误,欢迎指正),按照C语言的理解文件句柄是FILE*(fopen()返回),而文件描述符是fd(int型,open()函数返回),FILE这个结构体中有一个字段是_fileno,其就是指fd(文章末尾通过程序验证),且FILE*和fd可以通过C语言函数进行互相转换,故此笔者认为linux的文件句柄和文件描述符应该是一个一一对应的关系。文件指针即指FILE*,即指文件句柄。打开文件(open files)包括文件句柄但不仅限于文件句柄,由于linux所有的事物都以文件的形式存在,要使用诸如共享内存、信号量、消息队列、内存映射等都会打开文件,但这些是不会占用文件句柄。
ulimit
查看进程允许打开的最大文件句柄数:ulimit -n。设置进程能打开的最大文件句柄数:ulimit -n xxx。
ulimit在系统允许的情况下,提供对特定shell可利用的资源的控制(Provides control over the resources avaliable to the shell and to processes started by it, on systems that allow such control)。-H和-S选项设定指定资源的硬限制和软限制。硬限制设定之后不能再添加,而软限制则可以增加到硬限制规定的值。如果-H和-S选项都没有指定,则软限制和硬限制同时设定。限制值可以是指定资源的数值或者hard, soft, unlimited这些特殊值,其中hard代表当前硬限制, soft代表当前软件限制, unlimited代表不限制. 如果不指定限制值, 则打印指定资源的软限制值, 除非指定了-H选项.如果指定了不只一种资源, 则限制名和单位都会在限制值前显示出来.
[root@hidden ~]# ulimit -Sn
1024
[root@hidden ~]# ulimit -Hn
4096
需要注意的是ulimit提供的是对特定shell可利用的资源的控制,而shell是与具体用户相关的。因此ulimit提供的是对单个用户的限制。包括以下项:
[root@hidden ~]# 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) 62799
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) 65536
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
其中就有个“open files”的限制,默认是1024,也就是这个用户最大可以打开1024个文件。如果使用ulimit -n修改最大文件打开数,那么只对当前shell用户有用,同时也只对当前shell和这个shell fork出来的子shell生效,重启之后会重新恢复为默认值。
limits.conf
limits.conf这个文件是在/etc/security/目录下,因此这个文件是出于安全考虑的。limits.conf文件是用于提供对系统中的用户所使用的资源进行控制和限制,对所有用户的资源设定限制是非常重要的,这可以防止用户发起针对处理器和内存数量等的拒绝服务攻击。这些限制必须在用户登录时限制。
[root@hidden ~]# cat /etc/security/limits.conf
(省略若干....)
# End of file
apps soft nofile 65535
apps hard nofile 65535
apps soft nproc 10240
apps hard nproc 10240
其中含义如下:
-
第一列表示域(domain),可以使用用户名(root等),组名(以@开头),通配置*和%,%可以用于%group参数。
-
第二列表示类型(type),值可以是soft或者hard
-
第三列表示项目(item),值可以是core, data, fsize, memlock, nofile, rss, stack, cpu, nproc, as, maxlogins, maxsyslogins, priority, locks, msgqueue, nie, rtprio。其中nofile(Number of