现在的位置: 首页 > 综合 > 正文

在Linux下的进程资源的限制(struct rlimit)详解

2013年03月16日 ⁄ 综合 ⁄ 共 4605字 ⁄ 字号 评论关闭

在Linux系统中,Resouce limit指在一个进程的执行过程中,它所能得到的资源的限制,比如进程的corefile的最大值,虚拟内存的最大值等。

Resouce limit的大小可以直接影响进程的执行状况。其有两个最重要的概念:soft limit 和 hard limit。

soft limit是指内核所能支持的资源上限。比如对于RLIMIT_NOFILE(一个进程能打开的最大文件 数,内核默认是1024),soft limit最大也只能达到1024。对于RLIMIT_CORE(core文件的大小,内核不做限制),soft limit最大能是unlimited。

hard limit在资源中只是作为soft limit的上限。当你设置hard limit后,你以后设置的soft limit只能小于hard limit。要说明的是,hard limit只针对非特权进程,也就是进程的有效用户ID(effective user ID)不是0的进程。具有特权级别的进程(具有属性CAP_SYS_RESOURCE),soft limit则只有内核上限。

我们可以来看一下下面两条命令的输出。

sishen@sishen:~$ ulimit -c -n -s

core file size (blocks, -c) 0

open files (-n) 1024

stack size (kbytes, -s) 8192

sishen@sishen:~$ ulimit -c -n -s -H

core file size (blocks, -c) unlimited

open files (-n) 1024

stack size (kbytes, -s) unlimited

 

-H表示显示的是hard limit。从结果上可以看出soft limit和hard limit的区别。unlimited表示no limit, 即内核的最大值。

对于resoucelimit的读取修改,有两种方法。

使用shell内建命令ulimit

ulimit是改变shell的resouce limit,并达到改变shell启动的进程的resouce limit效果(子进程继承)。

usage:ulimit [-SHacdefilmnpqrstuvx [limit]]

当不指定limit的时候,该命令显示当前值。这里要注意的是,当你要修改limit的时候,如果不指定-S或者-H,默认是同时设置soft limit和hard limit。也就是之后设置时只能减不能增。所以,建议使用ulimit设置limit参数是加上-S。

 

使用getrlimit和setrlimit API函数

每个进程都有一组资源限制,其中某一些可以用getrlimit和setrlimit函数查询和更改。

#include

#include

int getrlimit(int resource,struct rlimit*rlptr);

int setrlimit(int resource,const structrlimit rlptr);

返回:若成功为0,出错为非0

对这两个函数的每一次调用都指定一个资源以及一个指向下列结构的指针。

struct rlimit{

rlim rlim ur;/* 软限制:当前限制 */

rlim rlim ax;/* 硬限制:rlimcur的最大值 */

};

这两个函数不属于POSIX.1,但SVR4和4.3+BSD提供它们。SVR4在上面的结构中使用基本系统数据类型rlim。其它系统则将这两个成员定义为整型或长整型。进程的资源限制通常是在系统初启时由0#进程建立的,然后由后续进程继承。在SVR4中,系统默认值可以查看文件/etc/conf/cfd/mtune在4.3+BSD中,系统默认值分散在多个头文件中。

在更改资源限制时,须遵循下列三条规则:

1.任何一个进程都可将一个软限制更改为小于或等于其硬限制。

2.任何一个进程都可降低其硬限制值,但它必须大于或等于其软限制值。这种降低,对普通用户而言是不可逆反的。

3.只有超级用户可以提高硬限制。

一个无限量的限制由常数RLIMNFINITY指定。

这两个函数的resource参数取下列值之一。注意并非所有资源限制都受到SVR4和4.3+BSD的支持。

RLMITCORE(SVR4及4.3+BSD)core文件的最大字节数,若其值为0则阻止创建core文件。

 

RLIMIT CPU(SVR4及4.3+BSD)CPU时间的最大量值(秒),当超过此软限止时,向该进程发送SIGXCPU信号。

 

RLIMIT ATA(SVR4及4.3+BSD)数据段的最大字节长度。这是图7.3中初始化数据、非初始化数据以及堆的总和。

 

RLIMIT SIZE(SVR4及4.3+BSD)可以创建的一个文件的最大字节长度。当超过此软限制时,则向该进程发送SIGFSZ信号。

 

RLIMIT EMLOCK(4.3+BSD)锁定在存储器地址空间(尚末实现)。

 

RLIMIT OFILE(SVR4)每个进程最多打开的文件数。更改此限制将影响到sysconf函数在参数-sc-OPEN-MAX中返回的值(2.5.4节)。见程序2.3。

 

RLIMIT PROC(4.3+BSD)每个实际用户ID所拥有的最大子进程数。更改此限制将影响到sysconf函数在参数 CHILDMAX中返回的值(2.5.4节)。

 

RLIMIT FILE(4.3+BSD)与SVR4的RLIMIT OFILE相同。

 

RLIMIT SS(4.3+BSD)最大驻内存集字节长度(RSS)。如果物理存储器供子应求,则系统核将从进程处取回超过RSS的部分。

 

RLIMIT TACK(SVR4及4.3+BSD)栈的最大字节长度。见图7.3。

 

RLIMIT MEM(SVR4)可映照地址空间的最大字节长度。这影响到mmap函数(12.9节)。

资源限制影响到调用进程并由其子进程继承。这就意味着为了影响一个用户的所有后续进程,需将资源限制设置构造在shell之中。确实,Bourne Shell和Kornshell具有内部ulimit命令,CShell具有内部limit命令。(umask和chdir也必须是shell内部的)。

 

RLIMIT_CPU

           CPU  time limit in seconds. Whenthe process reaches the soft limit, it is sent a SIGXCPU signal. The default actionfor 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 continuesto consume CPU time, it will be sent SIGXCPU once per second until the hard       limit is reached, at which time it issent SIGKILL. (This latter point describes Linux 2.2 and 2.4 behaviour.Implementations vary inhow they treat processes
which continue to consume CPUtime after reaching the soft limit. Portable applications that need to catchthis signal should perform an orderly termination uponfirst receipt ofSIGXCPU.)

CPU时间的最大量值(秒),当超过此软限制时向该进程发送SIGXCPU信号

 

RLIMIT_MEMLOCK

       The maximum number of bytes of virtual memory  that   may belocked into RAM using mlock() and mlockall().

 

RLIMIT_NOFILE

      Specifies  a value one greaterthan 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 forRLIMIT_NOFILE.

这里BSD系统中RLIMIT_NOFILE的别名

RLIMIT_NPROC

      The maximum number of processesthat can  be created for the real user IDof the calling process. Upon encountering this limit, fork() fails with theerror EAGAIN.

每个实际用户ID所拥有的最大子进程数,更改此限制将影响到sysconf函数在参数_SC_CHILD_MAX中返回的值

RLIMIT_RSS

     Specifies the limit (in pages) of the process鈙  resident  set (the number of virtual pages resident inRAM). This limit only has effect in Linux 2.4 onwatrds, and there onlyaffects       calls to madvise()specifying MADVISE_WILLNEED.

最大驻内存集字节长度(RSS)如果物理存储器供不应求则内核将从进程处取回超过RSS的部份

RLIMIT_STACK

     The maximum size of the process stack, in bytes. Upon reaching thislimit, a SIGSEGV signal is generated. To handle this signal, a process mustemploy an alternate signal stack (sigalt stack(2)).

栈的最大长度

RLIMIT——VMEM 可映照地址空间的最大字节长茺,这影响到mmap函数

这些限制影响到调用进程并由子进程继承!可以在SHELL中预设这些值ulimit命令设置

简单的用例:

#include<sys/time.h>

#include<sys/resource.h>

#include<unistd.h>

int main()

{

       struct rlimit limit;

       char p = '1';

       limit.rlim_cur = RLIM_INFINITY;

       limit.rlim_max = RLIM_INFINITY;

       if(setrlimit(RLIMIT_CORE, &limit))

       {

                printf("set limitfailed\n");

       }

       printf("p = %s\n",p);

}

抱歉!评论已关闭.