运行的程序会受到资源限制的影响,它们可能是硬件方面的物理性限制(如内存)系统策略的限制(允许使用的CPU时间)或具体实现的限制。
头文件limits.h中定义了许多代表操作系统方面限制的显式常量
限制常量 含义
NAME_MAX 文件名中的最大字符数
CHAR_BIT char类型值的位数
CHAR_MAX char类型的最大值
INT_MAX int类型的最大值
头文件sys/resource.h提供了资源操作方面的定义,其中包括对程序长度 执行优先级和文件资源等方面限制进行查询和设置的函数
#include
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
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#include #include #include #include #include #include /* 声明一个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,程序的执行时间变长了。