转自:http://blog.csdn.net/yetyongjin/article/details/7476860
这两天做asterisk的性能测试,经常碰到这样的错误:“Too many open files”。 我们知道,Linux下,文件描述符就是一个简单的整数值,习惯上,标准输入(standard input)的文件描述符是 0,标准输出(standard output)是 1,标准错误(standard error)是 2。POSIX 定义了STDIN_FILENO、STDOUT_FILENO 和STDERR_FILENO 来代替 0、1、2。这三个符号常量的定义位于头文件 unistd.h。
文件描述符的有效范围是0 到OPEN_MAX。那么一个进程最多到底能打开多少个文件描述符呢?下面,就以asterisk进程为例来说明。
#ps –ef | grep asterisk
从第二列得到asterisk的PID为19488。
# cat /proc/19488/limits
红线一行说明asterisk进程最大能打开1024个文件描述符(不包含它的子进程或创建出来的线程)。在/proc/19488/task/目录下,详细列出了其下的子任务的情况,每个子文件夹里同样有一个limits文件,限定了各子任务的情况。
一个进程打开了几个文件描述符呢?
# ll /proc/19488/fd/
子目录fd中,详细列出了进程打开的每个文件描述符,同样,/proc/19488/task/XXXX/fd下也会有子任务打开的文件描述符的情况。要知道有几个,执行
# ll /proc/19488/fd/ | wc -l
怎样知道一个进程及其子进程和哪些文件有关联呢?lsof可以完成这工作。请注意,关联文件和打开文件描述符是两个不同的概念,关联文件的数量可能远远大于打开的文件描述符的数量。
# lsof | grep asterisk | wc –l
也可以用父进程的PID过滤
# lsof | grep 19488 | wc –l
我这里得到的值是9525
怎样修改文件描述符的限定呢?临时修改,可以通过ulimit。
# ulimit -SHn 2048
但是这样只能影响到当前的session,当终端重新连接或当前用户退出,配置就失效了。如果想永久变更需要编辑/etc/security/limits.conf 文件,添加如下两行:
* hard nofile 2048
* soft nofile 2048
内核参数对文件描述符也有限制,如果设置的值大于内核的限制,也是不行的:
查找file-max的内核参数:
# sysctl -a|grep file-max
更改file-max的内核参数:
# sysctl -w file-max=65535
Sysctl也是临时的,要想永久生效,可以通过更改sysctl的文件,编辑/etc/sysctl.conf文件,添加或修改以下一行:
fs.file-max=65535
需要注意的是,文件描述符的限制,不局限于这里描述的这些,还可能和进程的启动参数、用户的环境设置有关。当然,如果是进程BUG造成文件描述符没有及时关闭回收,这增大限制也只是治标,根本上还得修复BUG。
此外,lsof会列出系统中所占用的资源,但是这些资源不一定会占用打开的文件描述符(比如共享内存,信号量,消息队列,内存映射.等,虽然占用了这些资源,但不占用打开文件号),因此有可能出现cat /proc/sys/fs/file-max 的值小于lsof | wc -l。asterisk本身提供了一个启动脚本,名为safe_asterisk,脚本里面就对文件描述符做了一些设置。
posted on 2012-11-21 11:43
小果子 阅读(3447)
评论(0) 编辑 收藏 引用 所属分类:
学习笔记 、
Linux