Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1800266
  • 博文数量: 438
  • 博客积分: 9799
  • 博客等级: 中将
  • 技术积分: 6092
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-25 17:25
文章分类

全部博文(438)

文章存档

2019年(1)

2013年(8)

2012年(429)

分类: 系统运维

2012-03-29 13:06:26

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



  1. #include <sys/resource.h>

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

  3. int setrlimit(int resource, const struct rlimit *rlptr);

  4. 两者成功都返回0,错误都返回非0。


这两个函数作为SUS的XSI扩展被定义。一个进程的资源限制通常在系统被初始化的时候被进程0建立,然后被每个后继进程继承。每个实现都有它自己调整各种限制的方法。


这两个函数的每次调用都指单个资源和一个指向以下结构体的指针:


struct rlimit {
  rlim_t rlim_cur;  /* soft limit: current limit */
  rlim_t rlim_max;  /* hard limit: maximum value for rlim_cur */
};


管理资源限制改变的三个准则:


1、一个进程可以改变它的软限制为一个小于或等于它的硬限制的值;


2、一个进程可以把它的硬限制降低为一个大于或等于它的软限制的值,这个硬限制的降低对普通用户来说是不可逆的。


3、只有超级用户才能提升一个硬限制。


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


resource参数为以下的某个值。下表展示了哪些限制由SUS定义,和被各实现支持。

资源限制的支持
限制 XSI FreeBSD 5.2.1 Linux 2.4.22 Mac OS X 10.3 Solaris 9
RLIMIT_AS *   *   *
RLIMIT_CORE * * * * *
RLIMIT_CPU * * * * *
RLIMIT_DATA * * * * *
RLIMIT_FSIZE * * * * *
RLIMIT_LOCKS     *    
RLIMIT_MEMLOCK   * * *  
RLIMIT_NOFILE * * * * *
RLIMIT_NPROC   * * *  
RLIMIT_RSS   * * *  
RLIMIT_SBSIZE   *      
RLIMIT_STACK * * * * *
RLIMIT_VMEM   *     *

RLIMIT_AS:进程总的可用内存的最大字节尺寸。这会影响sbrk函数(1.11节)和mmap函数(14.9节)。

RLIMIT_CORE:一个核心文件的最大字节尺寸。一个值为0的限制会阻止创建一个核心文件。

RLIMIT_CPU:最大的CPU时间的秒数。当软限制被超过时,SIGXCPU信号会被发送给进程。

RLIMIT_DATA:数据段的最大字节尺寸:初始化数据,未初绐化数据和堆的总和。

RLIMIT_FSIZE:一个文件可以创建的最大字节尺寸。当软限制被超过时,进程会收到SIGXFSZ信号。

RLIMIT_LOCKS:一个进程能拥有的最大文件锁的数量。(这个数量也包括文件租约,一个Linux的特性。参考Linux的fcntl手册页。)

RLIMIT_MEMLOCK:一个进程可以用mlock锁住的最大内存字节数。

RLIMIT_NOFILE:每个进程打开文件的最大数量。改变这个限制影响参数为_SC_OPEN_MAX的sysconf函数的返回值。

RLIMIT_NPROC:每个真实用户ID的子进程的最大数量。改变这个限制影响参数为_SC_CHILD_MAX的sysconf函数的返回值。

RLIMIT_RSS:最大常驻集尺寸(resident set size, RSS)的字节数。如果可用物理内存没有了,内存从进程超过它们RSS的部分取得内存。

RLIMIT_SBSIZE:一个用户在任何给定的时间内可以消息的套接字缓冲的最大尺寸的字节数。

RLIMIT_STACK:栈的最大字节尺寸。

RLIMIT_VMEM:RLIMIT_AS的同义词。


资源限制影响了调用它的进程并由它的子进程继承。这意味着资源限制的设定需要在shell里完成以影响我们所有的将来的进程。确实,在Bourne shell、GNU Bourne-again shell和Korn shell有内置的ulimit命令,而C shell有内置的limit命令。(umask和chdir函数同样必须作为shell内置的。)


下面的代码打印了所有在系统上支持的资源限制的软限制和硬限制。为了在所有不同的实现上编译这个程序,我们必须选择性的包含不同的资源名。注意我们在把 rlim_t定义为一个unsigned long long而不是unsigned long的平台上必须使用一个不同的printf格式。



  1. #include <stdio.h>
  2. #if defined(BSD) || defined(MACOS)
  3. #include <sys/time.h>
  4. #define FMT "%21d "
  5. #else
  6. #define FMT "%10d "
  7. #endif
  8. #include <sys/resource.h>

  9. #define doit(name) pr_limits(#name, name)

  10. static void pr_limits(char *, int);

  11. int
  12. main(void)
  13. {
  14. #ifdef RLIMIT_AS
  15.     doit(RLIMIT_AS);
  16. #endif
  17.     doit(RLIMIT_CORE);
  18.     doit(RLIMIT_CPU);
  19.     doit(RLIMIT_DATA);
  20.     doit(RLIMIT_FSIZE);
  21. #ifdef RLIMIT_LOCKS
  22.     doit(RLIMIT_LOCKS);
  23. #endif
  24. #ifdef RLIMIT_MEMLOCK
  25.     doit(RLIMIT_MEMLOCK);
  26. #endif
  27.     doit(RLIMIT_NOFILE);
  28. #ifdef RLIMIT_NPROC
  29.     doit(RLIMIT_NPROC);
  30. #endif
  31. #ifdef RLIMIT_RSS
  32.     doit(RLIMIT_RSS);
  33. #endif
  34. #ifdef RLIMIT_SBSIZE
  35.     doit(RLIMIT_SBSIZE);
  36. #endif
  37.     doit(RLIMIT_STACK);
  38. #ifdef RLIMIT_VMEM
  39.     doit(RLIMIT_VMEM);
  40. #endif
  41.     exit(0);
  42. }

  43. static void
  44. pr_limits(char *name, int resource)
  45. {
  46.     struct rlimit limit;

  47.     if (getrlimit(resource, &limit) < 0) {
  48.         printf("getrlimit error for %s\n", name);
  49.         exit(1);
  50.     }
  51.     printf("%-14s ", name);
  52.     if (limit.rlim_cur == RLIM_INFINITY)
  53.         printf("(infinite) ");
  54.     else
  55.         printf(FMT, limit.rlim_cur);
  56.     if (limit.rlim_max == RLIM_INFINITY)
  57.         printf("(infinite)");
  58.     else
  59.         printf(FMT, limit.rlim_max);
  60.     putchar((int)'\n');
  61. }

注意我们使用了ISO C的字符创建操作符(#)在doit宏里,来产生每个资源名的字符串值。当我们说doit(RLIMIT_CORE);时,C预处理器把它展开为pr_limits("RLIMIT_CORE", RLIMIT_CORE);

程序输出(Linux 2.6.38-13-generic):
RLIMIT_AS      (infinite) (infinite)
RLIMIT_CORE             0 (infinite)
RLIMIT_CPU     (infinite) (infinite)
RLIMIT_DATA    (infinite) (infinite)
RLIMIT_FSIZE   (infinite) (infinite)
RLIMIT_LOCKS   (infinite) (infinite)
RLIMIT_MEMLOCK      65536      65536
RLIMIT_NOFILE        1024       4096
RLIMIT_NPROC   (infinite) (infinite)
RLIMIT_RSS     (infinite) (infinite)
RLIMIT_STACK      8388608 (infinite)


我们在讲完信号后,会在第10章的练习里继续讨论资源限制。
阅读(1489) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~