37 读书笔记:第7章 进程环境 (4)

7.11 getrlimit和setrlimit函数

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

       #include <sys/resource.h>

       int getrlimit(int resource, struct rlimit *rlim);
       int setrlimit(int resource, const struct rlimit *rlim);
        // 两个函数返回值:若成功则返回0,若出错则返回非0值

        进程的资源限制通常是在系统初始化时由进程0建立的,然后由每个后续进程继承。每种实现都可以用自己的方法对各种限制做出调整。

        对这两个函数的每一次调用都会指定一个资源以及一个指向下列结构的指针。有些平台定义rlimit_t为unsigned long long 而非unisgned long。

           struct rlimit {
               rlim_t rlim_cur;  /* Soft limit */
               rlim_t rlim_max;  /* Hard limit (ceiling for rlim_cur) */
           };

        更改资源限制时,须遵循下列三条规则:

        (1) 任何一个进程都可将一个软限制更改为小于或等于其硬限制值。

        (2) 任何一个进程都可降低其硬限制值,但它必须大于或等于其软限制值。这种降低对普通用户而言是不可逆的。

        (3) 只有超级用户进程可以提高硬限制值。

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

        RLIMIT_AS    进程可用存储区的最大总长度(字节)。这会影响sbrk函数和mmap函数。

        RLIMIT_CORE    core文件的最大字节数,若其值为0则阻止创建core文件。

        RLIMIT_CPU    CPU时间的最大值(秒),当超过此软限制时,该进程发送SIGXCPU信号。

        RLIMIT_DATA    数据段的最大字节长度。这是初始化数据段、非初始化以及堆的总和。

        RLIMIT_FSIZE    可以创建的文件的最大字节数。当超过此软限制时,则向该进程发送SIGXFSZ信号。

        RLIMIT_LOCKS (Early Linux 2.4 only)    一个进程可持有文件锁的最大数。

        RLIMIT_MEMLOCK    一个进程使用mlock(2)能够锁定在存储器中的最大字节数。

        RLIMIT_NOFILE    每个进程能打开的最大文件数。更改此限制将影响到sysconf函数在参数_SC_OPEN_MAX中返回的值。

        RLIMIT_NPROC    每个实际用户ID可拥有的最大子进程数。更改此限制将影响到sysconf函数在参数_SC_CHILD_MAX中返回的值。

        RLIMIT_RSS    最大驻内存集的字节长度。如果物理存储器供不应求,则内核将从进程取回超过RSS的部分。

        RLIMIT_STACK    栈的最大字节数。

        资源限制影响到调用进程并由其子进程继承。这就意味着为了影响一个用户的所有后续进程,需将资源限制的设置构造在shell之中。shell的内置命令可以查看资源限制值。

$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 15843
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 15843
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

        《UNIX环境高级编程》P166:程序清单7-8 打印当前资源限制(有改动)

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/resource.h>

#define FMT "%10ld "

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

static void pr_limits(char *name, int resource);

int main(void)
{
    doit(RLIMIT_AS);        // 进程可用存储区的最大长度
    doit(RLIMIT_CORE);      // core文件的最大字节数
    doit(RLIMIT_CPU);       // CPU时间的最大量值
    doit(RLIMIT_DATA);      // 数据段的最大字节长度
    doit(RLIMIT_FSIZE);     // 可以创建的文件的最大字节数
    doit(RLIMIT_MEMLOCK);   // 一个进程使用mlock(2)能够锁定在存储器中的最大字节长度
    doit(RLIMIT_NOFILE);    // 每个进程能打开的最大文件数
    doit(RLIMIT_NPROC);     // 每个实际用户ID可拥有的最大子进程数
    doit(RLIMIT_RSS);       // 最大驻内存集的字节长度
    doit(RLIMIT_STACK);     // 栈的最大字节长度

    exit(0);
}

static void pr_limits(char *name, int resource)
{
    struct rlimit   limit;

    if (getrlimit(resource, &limit) < 0)
        fprintf(stderr, "getrlimit error %s\n", name);
    printf("%-14s ", name);

    if (limit.rlim_cur == RLIM_INFINITY)
        printf("(infinite) ");
    else
        printf(FMT, limit.rlim_cur);

    if (limit.rlim_max == RLIM_INFINITY)
        printf("(infinite)");
    else
        printf(FMT, limit.rlim_max);

    putchar('\n');
}

        注意,在doit宏中使用了ISO C的字符串创建运算符(#),以便为每个资源名产生字符串值。例如

                doit(RLIMIT_CORE);

        这将由C预处理程序扩展为:

                pr_limits("RLIMIT_CORE", RLIMIT_CORE);

        在Ubuntu下运行此程序:

$ ./08
RLIMIT_AS      (infinite) (infinite)
RLIMIT_CORE             0 (infinite)
RLIMIT_CPU     (infinite) (infinite)
RLIMIT_DATA    (infinite) (infinite)
RLIMIT_FSIZE   (infinite) (infinite)
RLIMIT_MEMLOCK      65536      65536 
RLIMIT_NOFILE        1024       4096 
RLIMIT_NPROC        15843      15843 
RLIMIT_RSS     (infinite) (infinite)
RLIMIT_STACK      8388608 (infinite)

你可能感兴趣的:(读书笔记,《UNIX环境高级编程》)