运行的程序会受到资源限制的影响,它们可能是硬件方面的物理性限制(如内存)系统策略的限制(允许使用的CPU时间)或具体实现的限制。


头文件limits.h中定义了许多代表操作系统方面限制的显式常量

限制常量        含义

NAME_MAX   文件名中的最大字符数

CHAR_BIT      char类型值的位数

CHAR_MAX    char类型的最大值

INT_MAX        int类型的最大值


头文件sys/resource.h提供了资源操作方面的定义,其中包括对程序长度 执行优先级和文件资源等方面限制进行查询和设置的函数

#include <sys/resource.h>

int getpriority(int which,id_t who)

int setpriority(int which,id_t who,int priority)

int getrlimit(int resource,struct rlimit * r_limit)

int setrlimit(int resource,const struct rlimit * r_limit)

int getrusage(int who,struct rusage * r_usage)


id_t是一个整数类型,用于用户和组标识符。在sys/resource.h中rusage结构用来确定当前程序已耗费了多少CPU时间,至少包含下列两个成员


struct timeval ru_utime      使用的用户时间

struct timeval ru_stime      使用的系统时间


timeval结构定义在sys/time.h中,它包含成员tv_sec和tv_usec,分别代表秒和微秒。


一个程序耗费的CPU时间分为用户时间(程序执行自身的指令所耗费的时间)和系统时间(操作系统为程序执行所耗费的时间,即执行输入输出操作的系统调用或其他系统函数所花费的时间。)


getrusage函数将CPU时间信息写入参数r_usage指向的rusage结构中。参数who可以是下列常量

who常量                           说明

RUSAGE_SELF               仅返回当前程序的使用信息

RUSAGE_CHILDREN      还包括子进程的使用信息


优先级越高的程序将分配到更多的CPU可用时间。

普通用户只能降低其程序的优先级,而不能提高。

应用程序可以用getpriority和setpriority函数来确定和更改它们的优先级。被优先级函数检查或更改的进程可以用进程标识符 组标识符或用户来确定。which参数指定了对待who参数的方式。

which参数                    说明

PRIO_PROCESS              who参数是进程标识符

PRIO_PGRP                     who参数是进程组

PRIO_USER                     who参数是用户标识符


为确定当前进程的优先级,可以调用

priority=getpriority(PRIO_PROCESS,getpid());

setpriority函数用于设置一个新的优先级。默认优先级是0,正数优先级用于后台任务,它们只在没有其他更高优先级的任务准备运行时才执行。负数优先级使一个程序运行更频繁,获得更多的CPU使用时间。优先级的有效范围是-20~19,很容易让人困惑,数值越高,执行优先级越低。

getpriority在成功时返回一个有效的优先级,失败返回-1并设置errno变量。-1本身是一个有效的优先级,所以在调用getpriority之前应将errno变量设置为0,并在函数返回时检查它是否仍为0。setpriority在成功时返回0,否则返回-1。


系统资源方面的限制可以通过getrlimit和setrlimit来读取和设置。

#include <sys/resource.h>

struct rlimit

{

    rlimit_t     rlim_cur,        当前的软限制

    rlimit_t     rlim_max,       硬限制

}

rlimit_t是一个整数类型,它用来描述资源级别。一般来说,软限制是一个建议性的最好不要超越的限制,如果超越可能会导致库函数返回错误。硬限制如果被超越,则可能会导致系统通过发送信号的方式来终止程序的执行。如CPU时间限制被超越时系统会发送SIGXCPU信号,数据长度限制被超越时系统会发送SIGSEGV信号。程序可以把自己的软限制设置为小于硬限制的任何值。它也可以减小自己的硬限制。只有超级用户权限运行的程序才能增加硬限制。

rlimit函数中的resource参数指定,在头文件sys/resource.h中定义

resource参数                       说明

RLIMIT_CORE                      内核转储文件的大小限制   单位字节

RLIMIT_CPU                         CPU时间限制          单位秒

RLIMIT_DATA                        数据段限制             单位字节

RLIMIT_FSIZE                       文件大小限制           单位字节

RLIMIT_NOFILE                    可以打开的文件数限制  

RLIMIT_STACK                      栈大小限制                 单位字节

RLIMIT_AS                            地址空间(栈和数据)限制     单位字节


实验:

/*
 * limits.c
 *
 *  Created on: Jul 27, 2013
 *      Author: root
 */
#include <sys/types.h>
#include <sys/resource.h>
#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
/* 声明一个test函数 */
void test()
{
    /* 定义变量 */
        FILE * f;
        int i;
        double x=1.123;
        f = tmpfile();     //创建一个临时文件并打开它
        /* 将一个字符串写入一个临时文件10000次 */
        for (i = 0; i < 10000; i++) {
            fprintf(f, "Write 10000 times");
            if (ferror(f)) {
                fprintf(stderr, "Writing Error!");
                exit(1);
            }
        }
        /* 做些运算让cpu产生负载 */
        for(i=0;i<1000000;i++)
        {
            x=log(x*x+2.1);
        }
}
/*main函数调用test函数,然后用getrusage函数来发现它耗费的CPU时间*/
int main(int argc, char **argv) {
    struct rusage r_usage;
    struct rlimit r_limit;
    int priority;
    test();
    getrusage(RUSAGE_SELF,&r_usage);
    printf("CPU usage:User=%ld.%6ld,System=%ld.%6ld",r_usage.ru_utime.tv_sec,r_usage.ru_utime.tv_usec,r_usage.ru_stime.tv_sec,r_usage.ru_stime.tv_usec);
   /* 調用getpriority和getrlimit函數來获取当前优先级和文件大小限制*/
    priority=getpriority(PRIO_PROCESS,getpid());
    printf("Current Priority=%d\n",priority);
    getrlimit(RLIMIT_FSIZE,&r_limit);
    printf("Current FSIZE limit:soft=%ld,hard=%ld\n",r_limit.rlim_cur,r_limit.rlim_max);
    /* 用setrlimit设置文件大小限制,然后再次调用test()函数 */
    r_limit.rlim_cur=2048;
    r_limit.rlim_max=4096;
    printf("Setting a 2k file size limit\n");
    setrlimit(RLIMIT_FSIZE,&r_limit);
    test();
    return 0;
}

运行

[root@localhost C_test]# gcc -o limits limits.c -lm
[root@localhost C_test]# ./limits
CPU usage:User=0. 57991,System=0.  2999Current Priority=0
Current FSIZE limit:soft=-1,hard=-1
Setting a 2k file size limit
File size limit exceeded (core dumped)
[root@localhost C_test]# nice -n 10 ./limits
CPU usage:User=0. 54991,System=0.  8998Current Priority=10
Current FSIZE limit:soft=-1,hard=-1
Setting a 2k file size limit
File size limit exceeded (core dumped)

用nice命令启动程序来改变程序的优先级,可以看到程序的优先级变成了+10,程序的执行时间变长了。