极限测试1 - 进程能打开的最大文件个数

################################################################################
一个进程,能打开的最大文件个数
################################################################################
打开文件是什么意思?
 
打开文件是为了获得操作这个文件的句柄。句柄是用来标识对象的。
对句柄形象的理解是你把东西存到管理处,拿到一个存储格子的号码。
如果句柄是一个整数(文件句柄就是这样),更容易想到它的实现是一个固定地址的数组。
 
句柄的实现, 也可以是一个指针。
应用程序启动后,组成这个程序的各对象是住留在内存的。如果简单地理解,似乎我们只要获知这个内存的首地址,
那么就可以随时用这个地址访问对象。
但是,系统内存管理器经常在内存中来回移动对象,以此来满足各种应用程序的内存需要。
对象被移动意味着它的地址变化了。如何满足这种要求。
 
为了解决这个问题,操作系统为各应用程序腾出一些内存储地址,用来专门登记各应用对象在内存中的地址变化,
而这个地址(存储单元的位置)本身是不变的。内存管理器在移动对象位置后,把对象新的地址告知这个句柄地址来保存。
这样我们只需记住这个句柄地址就可以间接地知道对象具体在内存中的哪个位置。
这个地址是在对象装载(Load)时由系统分配给的,当系统卸载时(Unload)又释放给系统。  
 
句柄地址(稳定)→记载着→对象在内存中的地址(不稳定)  
 
程序退出会自动关闭文件句柄吗?
程序退出,分配的内存将全部归还系统, 未关闭的句柄也会归还。
------------------------------------------------------------
可打开的文件个数测试代码
------------------------------------------------------------
[hjj@hjj /home/testapp]$ cat fileopennum.c
#include <stdio.h>
#include <fcntl.h>
 
int main(int argc, char *argv[])
{
    int i=0;
    int fd;
    char name[256];
    while(1)
    {
        sprintf(name,"name%04d.tst",i);
        fd=open(name, O_WRONLY|O_CREAT,0777);
        if(fd == -1)
        {
            perror("error create file fd:");
            printf("file name:%s\n", name);
            break;
        }
        printf("%s opened,fd:%d\n", name,fd);
        i++;
    }
 
    printf("press a key to continue...\n");
    int c=getchar();
    return 0;
}
[hjj@hjj /home/testapp]$ make
g++ -g   -c -o fileopennum.o fileopennum.c
g++  -o fileopennum fileopennum.o
 
[hjj@hjj /home/testapp]$ ./fileopennum
name0000.tst opened,fd:3
name0001.tst opened,fd:4
name0002.tst opened,fd:5
....
name40953.tst opened,fd:40956
name40954.tst opened,fd:40957
name40955.tst opened,fd:40958
name40956.tst opened,fd:40959
error create file fd:: Too many open files
file name:name40957.tst
press a key to continue...
 
------------------------------------------------------------
lsof 查看打开的文件
------------------------------------------------------------
注意: fd 0,1,2 已经被保留为:stdin,stdout,stderr
下面命令,事件会很漫长...
[hjj@hjj /home/testapp]$ lsof |grep name
fileopenn 19077       hjj    3w      REG              253,2        0    3671931 /home/testapp/name0000.tst
fileopenn 19077       hjj    4w      REG              253,2        0    3673172 /home/testapp/name0001.tst
fileopenn 19077       hjj    5w      REG              253,2        0    3673179 /home/testapp/name0002.tst
fileopenn 19077       hjj    6w      REG              253,2        0    3673183 /home/testapp/name0003.tst
.....
 
下面命令,会很快...
[hjj@hjj /home/testapp]$ lsof -c fileopen
COMMAND     PID USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME
fileopenn 19077  hjj  cwd    DIR  253,2  1372160 3671071 /home/testapp
fileopenn 19077  hjj  rtd    DIR  253,0     4096       2 /
fileopenn 19077  hjj  txt    REG  253,2     9172 3671438 /home/testapp/fileopennum
fileopenn 19077  hjj  mem    REG  253,0   156928 1441817 /lib64/ld-2.12.so
fileopenn 19077  hjj  mem    REG  253,0  1926800 1441931 /lib64/libc-2.12.so
fileopenn 19077  hjj  mem    REG  253,0   599384 1442023 /lib64/libm-2.12.so
fileopenn 19077  hjj  mem    REG  253,0    93320 1447971 /lib64/libgcc_s-4.4.7-20120601.so.1
fileopenn 19077  hjj  mem    REG  253,0   989840 3100263 /usr/lib64/libstdc++.so.6.0.13
fileopenn 19077  hjj    0u   CHR  136,0      0t0       3 /dev/pts/0
fileopenn 19077  hjj    1u   CHR  136,0      0t0       3 /dev/pts/0
fileopenn 19077  hjj    2u   CHR  136,0      0t0       3 /dev/pts/0
fileopenn 19077  hjj    3w   REG  253,2        0 3671931 /home/testapp/name0000.tst
fileopenn 19077  hjj    4w   REG  253,2        0 3673172 /home/testapp/name0001.tst
fileopenn 19077  hjj    5w   REG  253,2        0 3673179 /home/testapp/name0002.tst
....
 
下面的命令,针对部分名称最合适,支持通配符。
[hjj@hjj /home/testapp]$ lsof name*
COMMAND     PID USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME
fileopenn 20373  hjj    3w   REG  253,2        0 3671931 name0000.tst
fileopenn 20373  hjj    4w   REG  253,2        0 3673172 name0001.tst
fileopenn 20373  hjj    5w   REG  253,2        0 3673179 name0002.tst
....
 
退出了程序,再用lsof name* 已经没有name...文件句柄了。
 
文件句柄的可打开个数,由一个系统参数控制,open files
[hjj@hjj /home/testapp]$ 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) 14706
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 40960
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) 10240
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited
 
------------------------------------------------------------
永久修改open files 个数限制。
------------------------------------------------------------
[hjj@hjj /home/testapp]$ cat /etc/security/limits.conf  
 
hjj        soft    nofile           40960
hjj        hard    nofile              40960  
# End of file
 
什么是硬限制,硬限制是实际的限制,而软限制,是warnning限制,只会給出warning,
ulimit命令本身就有分软硬设置,加-H就是硬,加-S就是软,没有加上的话,就是两个一起改
默认显示的是软限制.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值