C语言系统资源控制(getrlimit && setrlimit)
每一个进程都有自己的一组资源限制,在(*)inux系统中我们可以通过 #include<sys/resource.h> intgetrlimit(intresource,structrlimit*rlim); intsetrlimit(intresource,conststructrlimit*rlim); 这2个API来取得和设置资源 getrlimit用来取得setrlimit用来设置这二个参数都需要一个要控制的资源比如控制CPU、内存、文件描述符个数等等的控制,作为第一个参数传入,第二个参数是一个rlimit的结构体地址(指针),他的结构如下定义: 定义放在头文件/usr/include/bits/resource.h中 structrlimit { /*Thecurrent(soft)limit.*/ rlim_trlim_cur; /*Thehardlimit.*/ rlim_trlim_max; }; 结构体中rlim_cur是要取得或设置的资源软限制的值,rlim_max是硬限制 这两个值的设置有一个小的约束: 1)任何进程可以将软限制改为小于或等于硬限制 2)任何进程都可以将硬限制降低,但普通用户降低了就无法提高,该值必须等于或大于软限制 3)只有超级用户可以提高硬限制 一个无限的限制由常量RLIM_INFINITY指定(ThevalueRLIM_INFINITYdenotesnolimitonaresource) RLIMIT_AS Themaximumsizeoftheprocess鈙virtualmemory(address space)inbytes.Thislimitaffectscallstobrk(2),mmap(2) andmremap(2),whichfailwiththeerrorENOMEMuponexceeding thislimit.Alsoautomaticstackexpansionwillfail(andgen- erateaSIGSEGVthatkillstheprocesswhennoalternatestack hasbeenmadeavailable).Sincethevalueisalong,on machineswitha32-bitlongeitherthislimitisatmost2GiB, orthisresourceisunlimited. RLIMIT_CORE Maximumsizeofcorefile.When0nocoredumpfilesarecre- ated.Whennonzero,largerdumpsaretruncatedtothissize. 设定最大的core文件,当值为0时将禁止core文件非0时将设定产生的最大core文件大小为设定的值 RLIMIT_CPU CPUtimelimitinseconds.Whentheprocessreachesthesoft limit,itissentaSIGXCPUsignal.Thedefaultactionfor thissignalistoterminatetheprocess.However,thesignal canbecaught,andthehandlercanreturncontroltothemain program.IftheprocesscontinuestoconsumeCPUtime,itwill besentSIGXCPUonceperseconduntilthehardlimitis reached,atwhichtimeitissentSIGKILL.(Thislatterpoint describesLinux2.2and2.4behaviour.Implementationsvaryin howtheytreatprocesseswhichcontinuetoconsumeCPUtime afterreachingthesoftlimit.Portableapplicationsthatneed tocatchthissignalshouldperformanorderlyterminationupon firstreceiptofSIGXCPU.) CPU时间的最大量值(秒),当超过此软限制时向该进程发送SIGXCPU信号 RLIMIT_DATA Themaximumsizeoftheprocess鈙datasegment(initialized data,uninitializeddata,andheap).Thislimitaffectscalls tobrk()andsbrk(),whichfailwiththeerrorENOMEMupon encounteringthesoftlimitofthisresource. 数据段的最大字节长度 RLIMIT_FSIZE Themaximumsizeoffilesthattheprocessmaycreate. Attemptstoextendafilebeyondthislimitresultindelivery ofaSIGXFSZsignal.Bydefault,thissignalterminatesapro- cess,butaprocesscancatchthissignalinstead,inwhich casetherelevantsystemcall(e.g.,write(),truncate())fails withtheerrorEFBIG. 可以创建的文件的最大字节长度,当超过此软限制时向进程发送SIGXFSZ RLIMIT_MEMLOCK Themaximumnumberofbytesofvirtualmemorythatmaybe lockedintoRAMusingmlock()andmlockall(). RLIMIT_NOFILE Specifiesavalueonegreaterthanthemaximumfiledescriptor numberthatcanbeopenedbythisprocess.Attempts(open(), pipe(),dup(),etc.)toexceedthislimityieldtheerror EMFILE. 每个进程能够打开的最多文件数。更改此限制将影响到sysconf函数在参数_SC_CHILD_MAX中的返回值 RLIMIT_OFILEistheBSDnameforRLIMIT_NOFILE. 这里BSD系统中RLIMIT_NOFILE的别名 RLIMIT_NPROC Themaximumnumberofprocessesthatcanbecreatedforthe realuserIDofthecallingprocess.Uponencounteringthis limit,fork()failswiththeerrorEAGAIN. 每个实际用户ID所拥有的最大子进程数,更改此限制将影响到sysconf函数在参数_SC_CHILD_MAX中返回的值 RLIMIT_RSS Specifiesthelimit(inpages)oftheprocess鈙residentset (thenumberofvirtualpagesresidentinRAM).Thislimitonly haseffectinLinux2.4onwatrds,andthereonlyaffectscalls tomadvise()specifyingMADVISE_WILLNEED. 最大驻内存集字节长度(RSS)如果物理存储器供不应求则内核将从进程处取回超过RSS的部份 RLIMIT_STACK Themaximumsizeoftheprocessstack,inbytes.Uponreaching thislimit,aSIGSEGVsignalisgenerated.Tohandlethissig- nal,aprocessmustemployanalternatesignalstack(sigalt- stack(2)). 栈的最大长度 RLIMIT——VMEM可映照地址空间的最大字节长茺,这影响到mmap函数 这些限制影响到调用进程并由子进程继承!可以在SHELL中预设这些值ulimit命令设置 小试牛刀(代码只是演示,并没有作错误处理) #include<stdlib.h> #include<stdio.h> #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h> #include<unistd.h> #include<sys/resource.h> intmain(void) { structrlimitr; if(getrlimit(RLIMIT_NOFILE,&r)<0) { fprintf(stderr,"getrlimiterror\n"); exit(1); } printf("RLIMIT_NOFILEcur:%d\n",r.rlim_cur); printf("RLIMIT_NOFILE max:%d\n",r.rlim_max);/** set limit **/ r.rlim_cur=100; r.rlim_max=200; if(setrlimit(RLIMIT_NOFILE,&r)<0) { fprintf(stderr,"setrlimiterror\n"); exit(1); }/** get value of set **/ if(getrlimit(RLIMIT_NOFILE,&r)<0) { fprintf(stderr,"getrlimiterror\n"); exit(1); } printf("RLIMIT_NOFILEcur:%d\n",r.rlim_cur); printf("RLIMIT_NOFILEmax:%d\n",r.rlim_max); return0; } ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ :!gcc test.c:!./a.out RLIMIT_NOFILEcur:1024 RLIMIT_NOFILEmax:1024 RLIMIT_NOFILEcur:100 RLIMIT_NOFILEmax:200 |