C语言系统资源控制(getrlimit && setrlimit)
每一个进程都有自己的一组资源限制,在(*)inux系统中我们可以通过
#include <sys/resource.h>
int getrlimit(int resource, struct rlimit *rlim);
int setrlimit(int resource, const struct rlimit *rlim);
这2个API来取得和设置资源
getrlimit用来取得setrlimit用来设置 这二个参数都需要一个要控制的资源 比如控制CPU、内存、文件描述符个数等等的控制,作为第一个参数传入,第二个参数是一个rlimit的结构体地址(指针),他的结构如下定义:
定义放在头文件/usr/include/bits/resource.h中
struct rlimit
?????? {
???????? /* The current (soft) limit.?????? */
???????? rlim_t rlim_cur;
???????? /* The hard limit.?????? */
???????? rlim_t rlim_max;
?????? };
结构体中 rlim_cur是要取得或设置的资源软限制的值,rlim_max是硬限制
这两个值的设置有一个小的约束:
1) 任何进程可以将软限制改为小于或等于硬限制
2) 任何进程都可以将硬限制降低,但普通用户降低了就无法提高,该值必须等于或大于软限制
3) 只有超级用户可以提高硬限制
一个无限的限制由常量RLIM_INFINITY指定(The?????? value?????? RLIM_INFINITY?????? denotes no limit on a resource )
RLIMIT_AS
?????????????????? The?????? maximum?????? size?????? of?????? the?????? process鈙?????? virtual memory (address
?????????????????? space) in bytes.?????? This limit affects calls to?????? brk(2),?????? mmap(2)
?????????????????? and?????? mremap(2), which fail with the error ENOMEM upon exceeding
?????????????????? this limit. Also automatic stack expansion will fail (and?????? gen-
?????????????????? erate?????? a SIGSEGV that kills the process when no alternate stack
?????????????????? has been made available).??????? Since?????? the?????? value?????? is?????? a?????? long,?????? on
?????????????????? machines with a 32-bit long either this limit is at most 2 GiB,
?????????????????? or this resource is unlimited.
RLIMIT_CORE
?????????????????? Maximum size of core file. When 0 no core dump files?????? are?????? cre-
?????????????????? ated.?????? When nonzero, larger dumps are truncated to this size.
设定最大的core文件,当值为0时将禁止core文件非0时将设定产生的最大core文件大小为设定的值
RLIMIT_CPU
?????????????????? CPU?????? time?????? limit in seconds.?????? When the process reaches the soft
?????????????????? limit, it is sent a SIGXCPU signal.??????? The?????? default?????? action?????? for
?????????????????? this?????? signal?????? is to terminate the process.?????? However, the signal
?????????????????? can be caught, and the handler can return control to?????? the?????? main
?????????????????? program.?????? If the process continues to consume CPU time, it will
?????????????????? be sent SIGXCPU?????? once?????? per?????? second?????? until?????? the?????? hard?????? limit?????? is
?????????????????? reached,?????? at which time it is sent SIGKILL.?????? (This latter point
?????????????????? describes Linux 2.2 and 2.4 behaviour.?????? Implementations vary in
?????????????????? how?????? they?????? treat?????? processes?????? which continue to consume CPU time
?????????????????? after reaching the soft limit.?????? Portable applications that need
?????????????????? to catch this signal should perform an orderly termination upon
?????????????????? first receipt of SIGXCPU.)
CPU时间的最大量值(秒),当超过此软限制时向该进程发送SIGXCPU信号
RLIMIT_DATA
?????????????????? The maximum size of the?????? process鈙?????? data?????? segment?????? (initialized
?????????????????? data,?????? uninitialized data, and heap).?????? This limit affects calls
?????????????????? to brk() and sbrk(), which fail?????? with?????? the?????? error?????? ENOMEM?????? upon
?????????????????? encountering the soft limit of this resource.
数据段的最大字节长度
RLIMIT_FSIZE
?????????????????? The?????? maximum?????? size?????? of?????? files?????? that?????? the?????? process?????? may?????? create.
?????????????????? Attempts to extend a file beyond this limit result in?????? delivery
?????????????????? of a SIGXFSZ signal.?????? By default, this signal terminates a pro-
?????????????????? cess, but a process can catch this?????? signal?????? instead,?????? in?????? which
?????????????????? case the relevant system call (e.g., write(), truncate()) fails
?????????????????? with the error EFBIG.
可以创建的文件的最大字节长度,当超过此软限制时向进程发送SIGXFSZ
RLIMIT_MEMLOCK
?????????????????? The maximum number of bytes?????? of?????? virtual?????? memory?????? that?????? may?????? be
?????????????????? locked into RAM using mlock() and mlockall().
RLIMIT_NOFILE
?????????????????? Specifies?????? a value one greater than the maximum file descriptor
?????????????????? number that can be opened by this process.??????? Attempts?????? (open(),
?????????????????? pipe(),?????? dup(),?????? etc.)??????? to?????? exceed?????? this limit yield the error
?????????????????? EMFILE.
每个进程能够打开的最多文件数。更改此限制将影响到sysconf函数在参数_SC_CHILD_MAX中的返回值
RLIMIT_OFILE is the BSD name for RLIMIT_NOFILE.
这里BSD系统中RLIMIT_NOFILE的别名
RLIMIT_NPROC
?????????????????? The maximum number of processes that can?????? be?????? created?????? for?????? the
?????????????????? real?????? user?????? ID?????? of the calling process.?????? Upon encountering this
?????????????????? limit, fork() fails with the error EAGAIN.
每个实际用户ID所拥有的最大子进程数,更改此限制将影响到sysconf函数在参数_SC_CHILD_MAX中返回的值
RLIMIT_RSS
?????????????????? Specifies the limit (in pages) of the?????? process鈙?????? resident?????? set
?????????????????? (the number of virtual pages resident in RAM).?????? This limit only
?????????????????? has effect in Linux 2.4 onwatrds, and there only affects?????? calls
?????????????????? to madvise() specifying MADVISE_WILLNEED.
最大驻内存集字节长度(RSS)如果物理存储器供不应求则内核将从进程处取回超过RSS的部份
RLIMIT_STACK
?????????????????? The maximum size of the process stack, in bytes.?????? Upon reaching
?????????????????? this limit, a SIGSEGV signal is generated.?????? To handle this sig-
?????????????????? nal,?????? a?????? process must employ an alternate signal stack (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>
int main(void)
{
???? struct rlimit r;
???? if(getrlimit(RLIMIT_NOFILE,&r)<0)
???? {
???????? fprintf(stderr,"getrlimit error\n");
???????? exit(1);
???? }
???? printf("RLIMIT_NOFILE cur:%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,"setrlimit error\n");
???????? exit(1);
???? }
???? /** get value of set **/
???? if(getrlimit(RLIMIT_NOFILE,&r)<0)
???? {
???????? fprintf(stderr,"getrlimit error\n");
???????? exit(1);
???? }
???? printf("RLIMIT_NOFILE cur:%d\n",r.rlim_cur);
???? printf("RLIMIT_NOFILE max:%d\n",r.rlim_max);
???? return 0;
}
:!gcc test.c????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
:!./a.out
RLIMIT_NOFILE cur:1024
RLIMIT_NOFILE max:1024
RLIMIT_NOFILE cur:100
RLIMIT_NOFILE max:200