本站首页    管理页面    写新日志    退出


«August 2025»
12
3456789
10111213141516
17181920212223
24252627282930
31


公告

戒除浮躁,读好书,交益友


我的分类(专题)

日志更新

最新评论

留言板

链接

Blog信息
blog名称:邢红瑞的blog
日志总数:523
评论数量:1142
留言数量:0
访问次数:9693744
建立时间:2004年12月20日




[linux kernel]solaris里面fopen打开文件数的限制 
原创空间,  文章收藏,  网上资源,  软件技术,  电脑与网络

邢红瑞 发表于 2008/8/5 10:22:50

 cyt师傅说的,如果不用读写的话,open快,如果一般文本读写的话,fopen快。但如果自己控制的好,open的读写和fopen一样快。fopen打开的文件超过256后,再使用fopen时就会出错EMFILE,Too   many   open   files,但是使用open调用的时候就不会出现这个错误。用脚本tfc.sh保证所有的文件都存在     #!   /bin/sh         MAX=260     index=0     FILENAME=test         while   [   $index   -lt   $MAX   ]     do             touch   $FILENAME$index             index=`expr   $index   +   1`     donefopen的例子 如下:     #include         <stdio.h>     #include         <syslog.h>     #include         <errno.h>         #define           MAX           260     #define           FILENAME                 "test"         main()     {             int           i;             char         filename[256];             FILE         *fp;                 openlog("test1",   LOG_PID,   LOG_USER);             for   (i   =   0;   i   <   MAX;   i++)             {                     snprintf(filename,   256,   "%s%d",   FILENAME,   i);                     if   ((fp   =   fopen(filename,   "r"))   ==   NULL)                     {                             syslog(LOG_ERR,   "open   file   %s   error,   errno   %d",   filename,   errno);                     }             }             closelog();     }  open的例子#include         <stdio.h>     #include         <syslog.h>     #include         <errno.h>     #include         <sys/types.h>     #include         <sys/stat.h>     #include         <fcntl.h>         #define           MAX           260     #define           FILENAME                 "test"         main()     {             int           i;             char         filename[256];             int           fd;                 openlog("test2",   LOG_PID,   LOG_USER);             for   (i   =   0;   i   <   MAX;   i++)             {                     snprintf(filename,   256,   "%s%d",   FILENAME,   i);                     if   ((fd   =   open(filename,   O_RDONLY,   0))   ==   -1)                     {                             syslog(LOG_ERR,   "open   file   %s   error,   errno   %d",   filename,   errno);                     }             }             closelog();     }     这个程序不会出错,当然前提是ulimit   -H   -n和ulimit   -S   -n均大于256。1)修改了/etc/system中的定义,并重新启动了机器。set rlim_fd_max = 4096set rlim_fd_cur = 1024 2)在用户的.cshrc里面设置了 limit descriptors 1024 3)用命令 ulimit -Sn已经能看到改为了1024 但运行程序时,打开文件数目到256以后,再想打开文件,还是出错了.因为256的限制来自于FILE结构的实现。FILE里用unsigned char记录stream对应的描述符,所以只能是0~255。这个限制只在32位系统存在,对于64bit系统,FILE结构被重新定义了,不再有这个限制。open返回的是int,所以没有这个限制。其实fopen在 64位的solaris 2.8上也只能打开255个。改成open函数是可以。但open不能用像fprintf那样的函数进行格式化输出了。 sun专家的建议 Solaris中关于参数rlim_fd_max和rlim_fd_cur的设置讨论 一、概述 很多开发者在编程的时候经常遇到了文件描述符不够用的情况,比如说这样的一个程序,程序首先创建125个的管道(用 pipe(fd[2])来创建),但不释放,接着再打开文件,你就会发现只能打开6个文件,就再也不能打开文件了(fopen()函数返回错误)。按我们的经验觉得在Solaris 8上肯定不止这些文件描述符,但是确实只能使用125*2+6=256个文件描述符(因为一个管道拥有两个描述符)。其实程序能使用的文件描述符受 rlim_fd_max和rlim_fd_cur这两个kernal参数设置的限制,在/etc/system文件里即使把这两个参数值设置成最 65535,仍然只能再打开若干个文件后fopen函数就会返回错误值,但这两个参数的改变确实影响着程序的执行结果。   二、设置修改参数值 其实在系统里面有这样一个命令ulimit,以下是ulimit -a执行的结果:time(seconds) unlimitedfile(blocks) unlimiteddata(kbytes) unlimitedstack(kbytes) 8192coredump(blocks) unlimitednofiles(descriptors) 1024memory(kbytes) unlimited 其中nofiles就是文件描述符的变量值,该值受rlim_fd_cur这个参数的影响,可以用ulimit -n number命令来修改。但不管怎么改,程序仍然不能突破fd=256的限制。在Solaris Tunable Parameters Reference Manua这本书里面能查到以下的资料:A 32-bit program using standard I/O is limited to 256 file descriptors。A 64-bit program using standard I/O can use up to 2 billion descriptors。 这也就是说32位的程序是没有办法突破这个限制的,只有64位的程序才能使用高达2亿个文件描述符,SUN的软硬件在很早以前就实现了64位的架构,现在唯一要解决的就是将程序编译成64位程序,为了生成64位程序,就必须要有64位的编译器(其实不是这样的),如果你去www.sunfreeware.com下载64位编译器gcc,网站上没有特别注明是64位的gcc,但是会有个意外的收获,就是该软件的说明里面注明了只要在用gcc编译的时候加上-m64的option就能生成64位程序了。 于是用gcc -m64去编译生成一个64位程序后,用ulimit -n 102400将number of fd设成很大的情况下,所有问题迎刃而解,再也不存在文件描述符不够用的情况。 在/etc/system文件设置rlimi_fc_max和rlim_fd_cur格式如下:set rlim_fd_max=65535set rlim_fd_cur=102400 命令ulimit使用格式如下:usage: ulimit [ -HSacdfnstv ] [ limit ]ulimit -a是显示各参数的设置值,ulimit -n是用来设置fd的最大值的。 我写的测试代码 #include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>int main(){         int erron;         int size=0;         int max=0;    FILE *fp[1024];   int i;    char filename[256];    max=getdtablesize();     printf("max fd=%d\n ",max);   strcpy(filename,"./test.txt");   for(i=0;i<1024;i++){   if ((fp[i]=fopen(filename, "r"))==NULL){    printf("fopen() error %x\n",erron);    return -1;   }     printf("cur fd num:%d\n",i+1);   }    return 0;    } linux 没有这个限制。


阅读全文(7075) | 回复(0) | 编辑 | 精华
 



发表评论:
昵称:
密码:
主页:
标题:
验证码:  (不区分大小写,请仔细填写,输错需重写评论内容!)



站点首页 | 联系我们 | 博客注册 | 博客登陆

Sponsored By W3CHINA
W3CHINA Blog 0.8 Processed in 0.328 second(s), page refreshed 144754157 times.
《全国人大常委会关于维护互联网安全的决定》  《计算机信息网络国际联网安全保护管理办法》
苏ICP备05006046号