问题描述
- 有一个函数,负责文件合并,循环调用这个函数2300次左右,每一次都会生成一个新的文件,在第1014次的时候,总是出现fopen(filename ,“w”)总是返回NULL,而且报Segmentation fault(core dumped)的错误。这一段代码是别人写的,在其他机器上跑起来没有问题,不会有任何错误。但是在这台机器上却总是报这个错误。
解决过程
- 我们分析了一下,猜想会不会是因为系统为本用户(一个普通账户,无root权限)设置了配额,限制了可以使用的磁盘空间的大小,经过验证,发现没有设置配额。
- 为了解决问题,我自己重新写了一个函数,利用系统调用创建2500个文件,代码如下:
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
int main(){
int i;
int fd;
char err[256];
char filename[256];
for (i=0;i<2500;i++){
sprintf(filename,"/home/sportsg/dirs/tmp%d.txt",i);
fd=open(filename,O_CREAT);
if(fd==-1){
perror(err);
printf("error message : %s\n",err);
return -1;
}
close(fd);
}
return 0;
}
然后发现上面这一段函数执行时会出现错误,打印的错误信息是:too man open files
- 至此,问题算是清楚了,就是打开的文件数超过了系统允许打开的文件的上限
- 使用ulimit -a指令发现本机器系统设置的允许打开的最大的文件数为1024,在可以运行有问题函数的机器上系统设置的可以打开的文件数为65535。
解决方案
- 在允许打开最大文件数为1024的机器上有了问题,而在允许打开文件数为65535的机器上没有问题,说明那一段函数确实有问题,经过寻找,发现是因为open了dir却没有关闭,修复了代码之后,就可以了。
- 修改系统允许打开的最大文件数比如65535的操作如下:
方法1:使用ulimit -n 65535,该方法只是临时有效
方法2:在/etc/security/limits.conf文件中添加如下内容,该方法永久有效,该方法需要重新进入终端
* soft nofile 65535
* hard nofile 65535