進程環境之getrlimit和setrlimit函數


每個進程都有一組資源限制,其中一些可以用getrlimit和setrlimit函數查詢和更改。

#include <sys/resource.h>
int getrlimit( int resource, struct rlimit *rlptr );
int setrlimit( int resource, const struct rlimit *rlptr );
兩個函數返回值:若成功則返回0,若出錯則返回非0值

進程的資源限制通常是在系統初始化時由進程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參數取下列值之一:

RLIMIT_AS                進程可用存儲區的最大總長度(字節)。這回影響sbrk函數和mmap函數。

RLIMIT_CORE           core文件的最大字節數,若其值為0則阻止創建core文件。

RLIMIT_CPU             CPU時間的最大量值(秒),當超過此軟限制時,向該進程發送SIGXCPU信號。

RLIMIT_DATA            數據段的最大字節長度。這是初始化數據、非初始化數據以及堆的總和。

RLIMIT_FSIZE           可以創建的文件的最大字節長度。當超過此軟限制時,則向該進程發送SIGXFSZ信號。

RLIMIT_LOCKS          一個進程可持有的文件鎖的最大數(此數也包括Linux特有的文件租借數)。

RLIMIT_MEMLOCK     一個進程使用mlock(2)能夠鎖定在存儲器中的最大字節長度。

RLIMIT_NOFILE         每個進程能打開的最大文件數。更改此限制將影響到sysconf函數在參數_SC_OPEN_MAX中的返回值。

RLIMIT_NPROC          每個實際用戶ID可擁有的最大子進程數。更改此限制將影響到sysconf函數在參數_SC_CHILD_MAX中返回的值。

RLIMIT_RSS               最大駐內存集的字節長度(resident set size in bytes, RSS)。如果物理存儲器供不應求,則內核將從進程處取回超過RSS的部分。

RLIMIT_SBSIZE          用戶在任一給定時刻可以占用的套接字緩沖區的最大長度(字節)。(Linux 2.4.22不支持)

RLIMIT_STACK           棧的最大字節長度。

RLIMIT_VMEM           這是RLIMIT_AS的同義詞。(Linux 2.4.22不支持)

資源限制影響到調用進程並由其子進程繼承。這就意味着為了影響一個用戶的所有后續進行,需將資源限制的設置構造在shell之中。Bsh、Bash和Ksh具有內置的ulimit命令,Csh具有內置的limit命令。

程序7-8 打印當前資源限制

[root@localhost apue]# cat prog7-8.c
#include "apue.h"
#if defined(BSD) || defined(MACOS)
#include <sys/time.h>
#define FMT "%10lld "
#else
#define FMT "%10ld "
#endif
#include <sys/resource.h>

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

static void pr_limits(char *, int);

int 
main(void)
{
#ifdef  RLIMIT_AS
        doit(RLIMIT_AS);
#endif
        doit(RLIMIT_CORE);
        doit(RLIMIT_CPU);
        doit(RLIMIT_DATA);
        doit(RLIMIT_FSIZE);
#ifdef  RLIMIT_LOCKS
        doit(RLIMIT_LOCKS);
#endif
#ifdef  RLIMIT_MEMLOCK
        doit(RLIMIT_MEMLOCK);
#endif
        doit(RLIMIT_NOFILE);
#ifdef  RLIMIT_NPROC
        doit(RLIMIT_NPROC);
#endif
#ifdef  RLIMIT_RSS
        doit(RLIMIT_RSS);
#endif
#ifdef  RLIMIT_SBSIZE
        doit(RLIMIT_SBSIZE);
#endif
        doit(RLIMIT_STACK);
#ifdef  RLIMIT_VMEM
        doit(RLIMIT_VMEM
#endif
        exit(0);
}

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

        if(getrlimit(resource, &limit) < 0)
                err_sys("getrlimit error for %s", 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((int)'\n');
}

注意,在doit宏中使用了(也只能在宏中使用)ISO C的字符串創建運算符(#),以便為每個資源名產生字符串值。例如:

doit(RLIMIT_CORE);

這將由C預處理器擴展為:

pr_limits(“RLIMIT_CORE”, RLIMIT_CORE);

在Linux下運行此程序,得到:

[root@localhost apue]# ./prog7-8
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      32768      32768 
RLIMIT_NOFILE        1024       1024 
RLIMIT_NPROC         8192       8192 
RLIMIT_RSS     (infinite) (infinite) 
RLIMIT_STACK     10485760 (infinite)

本篇博文內容摘自《UNIX環境高級編程》(第二版),僅作個人學習記錄所用。關於本書可參考:http://www.apuebook.com/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM