之前开会大师兄问了下 'ulimit' 在底层用什么搞的,今天刚好遇到,就顺便写下来了。
内部有个“sys/resource.h”的库,里面主要有3个重要功能:
1. rlimit
2. rusage
3. priority
rlimit 挺好理解。rusage 跟 priority 不太懂,跟系统底层有关:一个是相关信息,一个是调度的优先级。
下面直接贴代码:
/*
* =====================================================================================
*
* Filename: rlimit.c
*
* Description: Resources limit test
*
* Version: 1.0
* Created: Thursday, December 22, 2011 07:20:02 HKT
* Revision: none
* Compiler: gcc
*
* Author: Hongchao Deng (fengjingchao), fengjingchao@gmail.com
* Company: Sun Yat-sen University
*
* =====================================================================================
*/
#include <errno.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/resource.h>
#include <sys/time.h>
#include <unistd.h>
/*
* === FUNCTION ======================================================================
* Name: work
* Description: This function writes a string to a temporary file 10,000 times and then
* performs some arithmetic to generate load on CPU. HOW BAD...
* =====================================================================================
*/
void
work ( )
{
FILE *f;
int i;
double x = 4.5;
f = tmpfile();
// Writing about 10K to the tmp file
for (i = 0; i < 10000; i++) {
/* code */
fprintf(f, "Do some output.\n");
if( ferror(f) )
{
fprintf(stderr,"Error while writing to temporary file.\n");
exit(EXIT_FAILURE);
}
}
for (i = 0; i < 1000000; i++) {
/* code */
x = log(x*x+3.21);
}
} /* ----- end of function work ----- */
/*
* === FUNCTION ======================================================================
* Name: rusage_test
* Description:
* =====================================================================================
*/
void
rusage_test ( )
{
struct rusage r_usage;
work();
getrusage(RUSAGE_SELF, &r_usage);
printf("\n**************************************\n");
printf ( "rusage information:\n" );
printf ( " ru_utime:\n tv_sec.tv_usec: %ld.%06ld (s)\n",
r_usage.ru_utime.tv_sec, r_usage.ru_utime.tv_usec );
printf ( " ru_stime:\n tv_sec.tv_usec: %ld.%06ld (s)\n",
r_usage.ru_stime.tv_sec, r_usage.ru_stime.tv_usec );
} /* ----- end of function rusage_test ----- */
/*
* === FUNCTION ======================================================================
* Name: main
* Description: main function
* =====================================================================================
*/
int
main ( int argc, char *argv[] )
{
// parameters
struct rlimit r_limit;
// todo
rusage_test();
rusage_test();
rusage_test();
printf("\n**************************************\n");
printf("priority information:\n");
printf(" process priority: %d\n", getpriority(PRIO_PROCESS,getpid()));
printf(" group priority: %d\n", getpriority(PRIO_PGRP,getgid()));
printf(" user priority: %d\n", getpriority(PRIO_PGRP,getuid()));
printf("\n**************************************\n");
printf("rlimit information: (RLIM_INFINITY=%ld)\n", RLIM_INFINITY);
getrlimit(RLIMIT_CPU, &r_limit);
printf ( " rlimit_cpu:\n s: %ld ; h: %ld\n", r_limit.rlim_cur, r_limit.rlim_max );
getrlimit(RLIMIT_DATA, &r_limit);
printf ( " rlimit_data:\n s: %ld ; h: %ld\n", r_limit.rlim_cur, r_limit.rlim_max );
getrlimit(RLIMIT_FSIZE, &r_limit);
printf ( " rlimit_fsize:\n s: %ld ; h: %ld\n", r_limit.rlim_cur, r_limit.rlim_max );
getrlimit(RLIMIT_NOFILE, &r_limit);
printf ( " rlimit_nofile:\n s: %ld ; h: %ld\n", r_limit.rlim_cur, r_limit.rlim_max );
getrlimit(RLIMIT_NPROC, &r_limit);
printf ( " rlimit_nproc:\n s: %ld ; h: %ld\n", r_limit.rlim_cur, r_limit.rlim_max );
printf("\nNow try to set some limits:\n");
r_limit.rlim_cur = 1024; r_limit.rlim_max = RLIM_INFINITY;
setrlimit(RLIMIT_FSIZE, &r_limit);
work();
return EXIT_SUCCESS;
} /* ---------- end of function main ---------- */
输出样例:
**************************************
rusage information:
ru_utime:
tv_sec.tv_usec: 0.040002 (s)
ru_stime:
tv_sec.tv_usec: 0.000000 (s)
**************************************
rusage information:
ru_utime:
tv_sec.tv_usec: 0.084005 (s)
ru_stime:
tv_sec.tv_usec: 0.000000 (s)
**************************************
rusage information:
ru_utime:
tv_sec.tv_usec: 0.128008 (s)
ru_stime:
tv_sec.tv_usec: 0.000000 (s)
**************************************
priority information:
process priority: 0
group priority: -1
user priority: -1
**************************************
rlimit information: (RLIM_INFINITY=-1)
rlimit_cpu:
s: -1 ; h: -1
rlimit_data:
s: -1 ; h: -1
rlimit_fsize:
s: -1 ; h: -1
rlimit_nofile:
s: 1024 ; h: 4096
rlimit_nproc:
s: 15915 ; h: 15915
Now try to set some limits:
File size limit exceeded
感悟:
1. 调用getrusage的时候,只是得到当前耗掉的时间,这点在上面我用了几次work中体现出来了。
2. priority是数值越小,优先越高。
3. 普通人set的时候只能变弱,即priority+,limit - 。superuser有能力set,但是在内核限制的范围内。
4. 为什么要有soft & hard limit 两种呢?查了下,是因为soft 是能提高的,但是hard普通用户只能减少,这样有个限度。
References:
http://linux.about.com/library/cmd/blcmdl2_setrlimit.htm
http://linux.die.net/man/2/getrusage
http://linux.die.net/man/2/gettimeofday
http://linux.die.net/man/2/setpriority
http://linux.die.net/man/2/nice
No comments:
Post a Comment