zoukankan      html  css  js  c++  java
  • Linux 软限制和硬限制

    每个进程的实际实现都有一组资源限制, 可以用getrlimit, setrlimit获取或设置

    1. getrlimit和setrlimit

    getrlimit和setrlimit, 能分别获取/设置当前进程的系统资源限制

    #include <sys/time.h>
    #include <sys/resource.h>
    
    int getrlimit(int resource, struct rlimit *rlim);
    int setrlimit(int resource, const struct rlimit *rlim);
    
    int prlimit(pid_t pid, int resource, const struct rlimit *new_limit, struct rlimit *old_limit);
    
    • 参数
      resource 资源编号, 具体含义见下表描述
      rlim 类型struct rlimit的参数, 用于记录/设置软限制(rlim_cur)和硬限制(rlim_max)
    struct rlimit {
                   rlim_t rlim_cur;  /* Soft limit */
                   rlim_t rlim_max;  /* Hard limit (ceiling for rlim_cur) */
               };
    
    • 返回值
      成功返回0; 失败, 返回-1, errno被设置

    • 附resource所有可能取值

    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不支持)

    2. 软限制和硬限制

    软限制: 对进程的资源数的限制的当前值, 可用getrlimit读取, setrlimit设置, 参数struct rlimitr.lim_cur. 软限制是限制的当前值, 小于等于 硬限制, 实际进程可以调用setrlimit增长到硬限制值. 也就是说, 软限制对进程并不是真正的限制.
    硬限制: 对进程的资源数的限制的最大值, 也可以用getrlimit读取/setrlimit设置, 参数struct rlimitr.rlim_max. 硬限制是绝对上限值, 进程增长资源数不会超过硬限制.

    3. 实验验证

    1) 以打开的文件数限制为例, 对应resource = RLIMIT_NOFILE
    首先, 打印其软限制和硬限制.
    然后, 通过open(O_CREAT | O_RDWR)方式打开文件, 一直到硬限制为止, 观察输出及错误情况.

    #include <sys/time.h>
    #include <sys/resource.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <unistd.h>
    
    #define FILENAMEMAX   100
    
    int main() 
    {
        struct rlimit lim;
        long int i;
        int fd;
        char filename[FILENAMEMAX];
    
        getrlimit(RLIMIT_NOFILE, &lim);
        printf("Soft limit = %ld, Hard limit = %ld
    ", lim.rlim_cur, lim.rlim_max);
    
        for (i = 0; i < lim.rlim_max; ++i) {
            snprintf(filename, sizeof(filename), "%d_%ld", getpid(), i);
            fd = open(filename, O_RDWR | O_CREAT | O_TRUNC, 0664);
    
            if (fd < 0) {
                fprintf(stderr, "open file %s error
    ", filename);
                exit(1);
            }
            else {
                printf("open file %s success
    ", filename);
            }
            // close(fd);
        }
    }
    

    输出结果见下, 可以知道成功打开了1021个文件(0~1020号), 到第1021个文件时, . 不过, 为什么不是软限制1024个呢?
    因为每个进程启动的时候, 已经默认打开了stdin, stdout, stderr这3个文件.

    Soft limit = 1024, Hard limit = 4096
    open file 17921_0 success
    open file 17921_1 success
    open file 17921_2 success
    open file 17921_3 success
    ...
    open file 17921_1018 success
    open file 17921_1019 success
    open file 17921_1020 success
    open file 17921_1021 error
    

    2) 在1)的基础上, 修改软限制, 使软限制 = 硬限制

    在printf和for之间, 添加setrlimit语句, 修改软限制

        getrlimit(RLIMIT_NOFILE, &lim);
        printf("Soft limit = %ld, Hard limit = %ld
    ", lim.rlim_cur, lim.rlim_max);
    
        /* 修改软限制 */
        lim.rlim_cur = lim.rlim_max;
        setrlimit(RLIMIT_NOFILE, &lim);
    
        for (i = 0; i < lim.rlim_max; ++i) {
            ...
        }
    

    再次运行, 程序可以打开4096个文件(包括stdin/stdout/stdout 3个文件)

    ...
    open file 19449_4090 success
    open file 19449_4091 success
    open file 19449_4092 success
    open file 19449_4093 error
    

    参考

    进程环境之getrlimit和setrlimit函数 | 博客园

  • 相关阅读:
    tar命令解压jdk.tar.gz包 报错 gzip: stdin: not in gzip format
    CentOS6.5安装完没有网络的解决办法
    UML在需求分析阶段的应用
    UML
    UML在软件开发中各个阶段的作用和意义
    Maven那点事儿(Eclipse版)
    eclipse和myeclipse的下载地址
    div的作用
    c:if标签数据回显判断是否选中
    《Hadoop》对于高级编程Hadoop实现构建企业级安全解决方案
  • 原文地址:https://www.cnblogs.com/fortunely/p/14855912.html
Copyright © 2011-2022 走看看