################################################################################
一个进程,能打开的最大文件个数
################################################################################
打开文件是什么意思?
打开文件是为了获得操作这个文件的句柄。句柄是用来标识对象的。
对句柄形象的理解是你把东西存到管理处,拿到一个存储格子的号码。
如果句柄是一个整数(文件句柄就是这样),更容易想到它的实现是一个固定地址的数组。
句柄的实现, 也可以是一个指针。
应用程序启动后,组成这个程序的各对象是住留在内存的。如果简单地理解,似乎我们只要获知这个内存的首地址,
那么就可以随时用这个地址访问对象。
但是,系统内存管理器经常在内存中来回移动对象,以此来满足各种应用程序的内存需要。
对象被移动意味着它的地址变化了。如何满足这种要求。
为了解决这个问题,操作系统为各应用程序腾出一些内存储地址,用来专门登记各应用对象在内存中的地址变化,
而这个地址(存储单元的位置)本身是不变的。内存管理器在移动对象位置后,把对象新的地址告知这个句柄地址来保存。
这样我们只需记住这个句柄地址就可以间接地知道对象具体在内存中的哪个位置。
这个地址是在对象装载(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就是软,没有加上的话,就是两个一起改
默认显示的是软限制.
一个进程,能打开的最大文件个数
################################################################################
打开文件是什么意思?
打开文件是为了获得操作这个文件的句柄。句柄是用来标识对象的。
对句柄形象的理解是你把东西存到管理处,拿到一个存储格子的号码。
如果句柄是一个整数(文件句柄就是这样),更容易想到它的实现是一个固定地址的数组。
句柄的实现, 也可以是一个指针。
应用程序启动后,组成这个程序的各对象是住留在内存的。如果简单地理解,似乎我们只要获知这个内存的首地址,
那么就可以随时用这个地址访问对象。
但是,系统内存管理器经常在内存中来回移动对象,以此来满足各种应用程序的内存需要。
对象被移动意味着它的地址变化了。如何满足这种要求。
为了解决这个问题,操作系统为各应用程序腾出一些内存储地址,用来专门登记各应用对象在内存中的地址变化,
而这个地址(存储单元的位置)本身是不变的。内存管理器在移动对象位置后,把对象新的地址告知这个句柄地址来保存。
这样我们只需记住这个句柄地址就可以间接地知道对象具体在内存中的哪个位置。
这个地址是在对象装载(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就是软,没有加上的话,就是两个一起改
默认显示的是软限制.