您的位置:首页 > 运维架构 > Linux

Linux中,getrlimit(),setrlimit(),getrusage()

2015-09-25 21:58 507 查看
一个进程在执行过程中有许多限制,比如运行时间的限制,内存使用的限制等,并且不同的用户限制不同.

在linux中,有两种方法可以获得并修改进程的限制,其一是通过系统调用,其二是在程序中调用库函数.

系统调用ulimit

通常在shell编程中用,如下:

[code]#!/bin/bash
ulimit -m 1  #空间限制1k
ulimit -t 1  #时间限制1s
./a          #执行a


具体可参考手册,”man ulimit”.

调用库函数

通过getrlimit()获得限制,setrlimit()修改限制.

通过”man getrlimit”获得使用手册,如下:

[code]#include <sys/time.h>
#include <sys/resource.h>

int getrlimit(int resource, struct rlimit *rlim);
int setrlimit(int resource, const struct rlimit *rlim);


int resource:指明何种资源,有如下资源:

1.RLIMIT_AS //进程的最大虚拟内存空间,字节为单位。

2.RLIMIT_CORE //内核转存文件的最大长度。

3.RLIMIT_CPU //最大允许的CPU使用时间,秒为单位。当进程达到软限制,内核将给其发送SIGXCPU信号,这一信号的默认行为是终止进程的执行;如果进程继续耗费CPU时间,核心会以每秒一次的频率给其发送SIGXCPU信号,直到达到硬限制,那时将给进程发送 SIGKILL信号终止其执行。

4.RLIMIT_DATA //进程数据段的最大值。

5.RLIMIT_FSIZE //进程可建立的文件的内容最大长度。如果进程试图超出这一限制时,核心会给其发送SIGXFSZ信号,默认情况下将终止进程的执行。

6.RLIMIT_LOCKS //进程可建立的锁和租赁的最大值。

7.RLIMIT_MEMLOCK //进程可锁定在内存中的最大数据量,字节为单位。

8.RLIMIT_MSGQUEUE //进程可为POSIX消息队列分配的最大字节数。

9.RLIMIT_NICE //进程可通过setpriority() 或 nice()调用设置的最大完美值。

10.RLIMIT_NOFILE //指定比进程可打开的最大文件描述词大一的值,超出此值,将会产生EMFILE错误。

11.RLIMIT_NPROC //用户可拥有的最大进程数。

12.RLIMIT_RTPRIO //进程可通过sched_setscheduler 和 sched_setparam设置的最大实时优先级。

13.RLIMIT_SIGPENDING //用户可拥有的最大挂起信号数。

14.RLIMIT_STACK //最大的进程堆栈,以字节为单位。

struct rlimit的原型声明:

struct rlimit {

rlim_t rlim_cur; /* Soft limit */

rlim_t rlim_max; /* Hard limit (ceiling for rlim_cur) */

};

rlim_t 是个int型值,类似size_t.

Soft limit即软限制,当进程所使用的资源超过Soft limit后操作系统会发送信号signal给该进程 ,Hard limit即硬限制,当进程所使用的资源达到其值时,操作系统也会发送信号给进程.当超过Solf limit时,一般程序还能运行,当超过HardSoft时,一般资源分配不成功,或者挂掉. limit小于等于Hard limit.

不同的资源操作系统发出的信号可能不同,进程收到信号处理也不相同.

以限制进程执行时间为例:

[code]#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/resource.h>
#include <sys/time.h>

int main()
{

    struct rlimit r;
    if(getrlimit(RLIMIT_CPU, &r) < 0)//获得默认执行时间
    {
        perror("getrlimit error");
        exit(1);
    }
    printf("RLIMIT_CPU cur %d\n", r.rlim_cur);
    printf("RLIMIT_CPU max %d\n", r.rlim_max);
    r.rlim_cur = 1; //修改软限制
    r.rlim_max = 2; //修改硬限制
    if(setrlimit(RLIMIT_CPU, &r) < 0) //修改限制
    {
        perror("setrlimit error");
        exit(1);
    }
    if(getrlimit(RLIMIT_CPU, &r) < 0)//重新获得限制
    {
        perror("getrlimit error");
        exit(1);
    }
    printf("RLIMIT_CPU cur %d\n", r.rlim_cur);
    printf("RLIMIT_CPU max %d\n", r.rlim_max);
    while(1) //测试超时系统的反应
        ;
    return 0;
}


编译执行:

gcc test.c -o test

./test

结果:

RLIMIT_CPU cur -1

RLIMIT_CPU max -1

RLIMIT_CPU cur 1

RLIMIT_CPU max 2

CPU time limit exceeded (core dumped)

getrusage()

程序执行过程中,可一通过库函数的调用,可查看进程执行过程中的信息,库函数getrusage().

同理查看手册,”man getrusage”:

[code] #include <sys/time.h>
 #include <sys/resource.h>

 int getrusage(int who, struct rusage *usage);


int who:指明查看谁的信息.

可以查看该进程的信息,也可查看由该进程创建子进程的信息,who = 0则表示自己,who = -1则表示子进程.

struct rusage *usage的原型声明:

struct rusage {

struct timeval ru_utime; /* user time used */

struct timeval ru_stime; /* system time used */

long ru_maxrss; /* max resident set size */

long ru_ixrss; /* integral shared memory size */

long ru_idrss; /* integral unshared data */

long ru_isrss; /* integral unshared stack */

long ru_minflt; /* page reclaims */

long ru_majflt; /* page faults */

long ru_nswap; /* swaps */

long ru_inblock; /* block input operations */

long ru_oublock; /* block output operations */

long ru_msgsnd; /* messages sent */

long ru_msgrcv; /* messages received */

long ru_nsignals; /* signals received */

long ru_nvcsw; /* voluntary context switches */

long ru_nivcsw; /* involuntary ” */

};

下面以查看本进程的信息为例:

[code]#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/resource.h>

int main()
{
    struct rusage start, end;
    if(getrusage(0, &start) < 0) //获得开始的信息 
    {
        perror("getrusage error");
        exit(1);
    }
    int k = 0;
    for(int i = 0; i < (int)1e10; ++i);
        k++;
    if(getrusage(0, &end) < 0) //获得结束的信息 
    {
        perror("getrusage error");
        exit(1);
    }
    //用户态执行时间
    double usertime = (end.ru_utime.tv_sec - start.ru_utime.tv_sec) + (end.ru_utime.tv_usec - start.ru_utime.tv_usec) / 10e6; 
    //内核态执行时间
    double kerneltime = (end.ru_stime.tv_sec - start.ru_stime.tv_sec) + (end.ru_stime.tv_usec - start.ru_stime.tv_usec) / 10e6;     printf("usertime %lf, kerneltime %lf\n", usertime, kerneltime); 
    printf("max resident set size %ld\n", start.ru_maxrss);
    printf("integral shared memory size %ld\n", start.ru_ixrss);
    return 0;
}


编译运行:

gcc test.c -o test

./test

结果:

usertime 4.041600, kerneltime 0.000400

max resident set size 1876

integral shared memory size 0

更加详细的文章: getrlimit,setrlimit,getrusage

更多细节,请自主查看man手册.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: