C/C++:进程资源限制函数(getrlimit、setrlimit)&& Shell-ulimit命令

进程在操作系统内核中是一个独立存在的运行实体。

每个进程都有 一组 资源限制 ,限制进程对于系统资源的申请量。

可以通过 getrlimit 来获取当前进程某一指定资源的限制。

可以通过 setrlimit 来设置当前进程某一指定资源的限制。

进程的资源限制通常是在系统初始化时由0进程建立的,然后后续进程继承。

即:进程的资源限制,是继承自fork当前进程的那个进程—父进程。

#include <sys/time.h>
#include <sys/resource.h>
int getrlimit(int resource, struct rlimit *rlim);
int setrlimit(int resource, const struct rlimit *rlim);
struct rlimit
    lim_t rlim_cur;   /* Soft limit */
    rlim_t rlim_max;  /* Hard limit (ceiling for rlim_cur) */

rlimit 的结构可以看出,每个进程每种资源限制分为两种:1)硬限制;2)软限制;

在设置进程的资源限制时,有三条规则:

1)进程可以将某资源的软限制值更改为小于或等于其硬限制值;

2)任何一个进程可以降低某资源的硬限制值,但必须大于等于对应资源的软限制值,且这种“降低”对于非root用户是不可逆的;

3)只有root用户进程可以提高硬限制值;

资源限制有多种,我列举下比较常用,比较关心的几类:

RLIMIT_CORE

进程core时,core文件最大字节数(单位字节),若其值为0则不创建core文件。

RLIMIT_FSIZE

每个进程可创建的文件的最大字节长度(单位字节)。

RLIMIT_NOFILE

每个进程能打开的最大文件数目。

RLIMIT_NPROC

每个实际用户ID可拥有的最大子进程数目。

Case:列出当前进程的软硬资源限制。

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/time.h>
#include <sys/resource.h>
#define doit(name) limit(#name, name)
static void limit(const char *name, int resource)
    struct rlimit limit;
    unsigned long long value;
    if (getrlimit(resource, &limit) != 0)
        printf("getrlimit %s = %d(%s)\n", name, errno, strerror(errno)); 
        return;
    printf("%-16s", name);
    if (limit.rlim_cur == RLIM_INFINITY)
        printf("%-10s", "infinite");
        value = limit.rlim_cur;
        printf("%-10lld", value);
    if (limit.rlim_max == RLIM_INFINITY)
        printf("%-10s", "infinite");
        value = limit.rlim_cur;
        printf("%-10lld", value);
    printf("\n");
int main()
#ifdef RLIMIT_CORE
    doit(RLIMIT_CORE);
#else
    printf("RLIMIT_CORE NOT SUPPORTED\n");
#endif
#ifdef RLIMIT_FSIZE
    doit(RLIMIT_FSIZE);
#else
    printf("RLIMIT_FSIZE NOT SUPPORTED\n");
#endif
#ifdef RLIMIT_NOFILE
    doit(RLIMIT_NOFILE);
#else
    printf("RLIMIT_NOFILE NOT SUPPORTED\n");
#endif
#ifdef RLIMIT_NPROC
    doit(RLIMIT_NPROC);
#else
    printf("RLIMIT_NPROC NOT SUPPORTED\n");
#endif
#ifdef RLIMIT_VMEM
    doit(RLIMIT_VMEM);
#else
    printf("RLIMIT_VMEM NOT SUPPORTED\n");
#endif
    return 0;

编译 && 运行:

[jiang@localhost 0520]$ gcc -o resource resource.c
[jiang@localhost 0520]$ ./resource 
RLIMIT_CORE     1048576   1048576   
RLIMIT_FSIZE    infinite  infinite  
RLIMIT_NOFILE   4096      4096      
RLIMIT_NPROC    1024      1024      
RLIMIT_VMEM NOT SUPPORTED

通过以上输出结果,我们可以知晓进程资源限制情况。

例如,进程的core文件限制是1024*1024=1048576字节,1024KB。

Shell内部命令—ulimit

在shell中man ulimit,可以看到ulimit的功能:

Provides control over the resources available to the shell and to processes started by it.

ulimit可以提供对shell进程本身以及由shell进程fork出来的进程的资源控制。

说到这里,我倒是想先提一下,对于shell来说,我们输入的命令分类。

第一种是外部命令。

外部命令是一个可执行文件,当我们执行外部命令时,通常是这样子的:

1)shell(记为shell-father)在终端IO操作读取外部命令的名字,然后fork出一个新的shell子进程(记为shell-son);

2)shell-son也是知道外部命令的名字的,然后shell-son执行exec系统调用,执行指定的外部命令程序;

3)shell-father在 fork shell-son 后就一直waitpid或者wait(假设外部命令启动在前台),阻塞(直到wait返回);

4)shell-son进程体(或者称为外部命令执行进程更合适)执行完毕,exit退出进程(内核发SIGCHLD给shell-father);

5)shell-father在wait到刚刚fork出的shell-son进程体,从wait/waitpid阻塞中返回,然后继续在终端进行IO操作。

shell-son知道要执行的外部命令的名字,是由于shell-father在fork后,这两个进程是一样样的,父进程有的数据,子进程也有完全相同的一份;

shell-son的前三个fd,是继承自shell-father的stdin、stdout、stderr。

举个栗子:

shell-son的fd=1和shell-father的fd=1指向同一个内核中的文件表(共享偏移量等),也就是指向的是同一个文件,只不过这个文件是标准输出。

所以,当shell-son在stdout输出和shell-father在stdout输出,都是到同一个文件,即同一个终端。

第二种是内部命令。

外部命令是由当前shell执行fork并在子进程中exec执行的命令。

内部命令是由当前shell直接执行,不经过fork以及exec系统调用完成的内部操作。

常见的有cd、ulimit等命令。

shell从终端输入上读取到 cd xxx 时,shell会解析xxx为一个路径,然后修改当前shell进程的内部变量值,以完成cd操作。

ulimit命令同理。

当进程读取到ulimit命令时,将解析ulimit命令后面的参数信息,然后执行setrlimit和getrlimit操作,修改当前shell的资源限制。

我们再一次回想man手册中对ulimit的描述:

Provides control over the resources available to

the shell (内部命令,当前shell进程自身

and to

processes started by it(外部命令,由当前shell fork出来的子进程,子进程的资源限制继承自当前shell进程).

下面简单介绍下shell ulimit内部命令。

ulimit [-SHacdefilmnpqrstuvx [limit]]
-H = hard
-S = soft
-a     All current limits are reported
-c     The maximum size of core files created
-f     The maximum size of files written by the shell and its children
-n     The maximum number of open file descriptors (most systems do not allow this value to be set)
-q     The maximum number of bytes in POSIX message queues
-u     The maximum number of processes available to a single user

Case 1:列出当前shell的资源软/硬限制

资源软限制:

[jiang@localhost ~]$ ulimit -Sa
core file size          (blocks, -c) 1024
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 3810
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) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 1024
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

资源硬限制:

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

我们可以观察到,对于CORE文件大小,当前shell的软限制是1024,硬限制是2048。

Case 2:修改当前shell的资源软硬限制

资源硬限制:

[jiang@localhost ~]$ ulimit -Hc
[jiang@localhost ~]$ ulimit -Hc 1408
[jiang@localhost ~]$ ulimit -Hc 1280
[jiang@localhost ~]$ ulimit -Hc 1152
[jiang@localhost ~]$ ulimit -Hc 1024
[jiang@localhost ~]$ ulimit -Hc 1280
-bash: ulimit: core file size: cannot modify limit: Operation not permitted

最开始,当前shell的CORE大小资源硬限制为2048,然后不断改小,设置为1408、1280、1152、1024都是可以的。

在当前shell的CORE大小资源硬限制为1024时,尝试设置其为更大的一个数值,1280,结果操作不被允许,执行失败。

硬限制只能向低的值设置,非特权用户不能提高资源硬限制值。

资源软限制:

[jiang@localhost ~]$ ulimit -Sc
[jiang@localhost ~]$ ulimit -Hc
[jiang@localhost ~]$ ulimit -Sc 1152
[jiang@localhost ~]$ ulimit -Sc 1280
[jiang@localhost ~]$ ulimit -Sc 1408
[jiang@localhost ~]$ ulimit -Sc
[jiang@localhost ~]$ ulimit -Hc

最开始当前shell的CORE资源软限制为1024,资源硬限制为2048,逐渐增大资源软限制值为1152、1280、1408。

资源软限制可以不断增大,但不能超过资源硬限制值的大小。

Case 3:资源限制在进程间的继承

Code:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/time.h>
#include <sys/resource.h>
#define doit(name) limit(#name, name)
static void limit(const char *name, int resource)
    struct rlimit limit;
    unsigned long long value;
    if (getrlimit(resource, &limit) != 0)
        printf("getrlimit %s = %d(%s)\n", name, errno, strerror(errno)); 
        return;
    printf("%-16s", name);
    if (limit.rlim_cur == RLIM_INFINITY)
        printf("%-10s", "infinite");
        value = limit.rlim_cur;
        printf("%-10lld", value);
    if (limit.rlim_max == RLIM_INFINITY)
        printf("%-10s", "infinite");
        value = limit.rlim_cur;
        printf("%-10lld", value);
    printf("\n");
int main()
#ifdef RLIMIT_CORE
    doit(RLIMIT_CORE);
#else
    printf("RLIMIT_CORE NOT SUPPORTED\n");
#endif
    return 0;

查看当前shell的CORE文件大小资源限制:

[jiang@localhost 0520]$ ulimit -Hc
[jiang@localhost 0520]$ ulimit -Sc

编译 && 执行上述程序:

[jiang@localhost 0520]$ gcc -o resource resource.c 
[jiang@localhost 0520]$ ./resource 
RLIMIT_CORE     1048576   1048576

在子进程中,资源软硬限制都是1024KB。

于是我猜测(注意,我没看过源码,只是实验得出的一个可能的猜测哈!):

子进程中的资源软硬限制 都是 直接继承自父进程的 软限制值 ,和父进程的 硬限制值 无关。

Case 4:修改系统配置,改变某用户对于某种资源的限制值

相关配置路径为:

/etc/security/limits.conf

[root@localhost ~]# cat /etc/security/limits.conf | grep -v "^#" | grep -v "^$"
*       soft    core    1024
*       hard    core    2048

当前配置为:任意用户的CORE文件大小硬限制为2048,软限制为1024。(单位通常为KB)

[jiang@localhost ~]$ ulimit -Hc
[jiang@localhost ~]$ ulimit -Sc

我想要修改用户jiang的CORE文件大小硬限制为4096,软限制为2048。

[jiang@localhost ~]$ cat /etc/security/limits.conf | grep -v "^$" | grep -v "^#"
*       soft    core    1024
*       hard    core    2048
jiang       soft    core    2048
jiang       hard    core    4096
[jiang@localhost ~]$ ulimit -Hc
[jiang@localhost ~]$ ulimit -Sc

修改/etc/security/limits.conf配置文件不必重启服务,当修改完并保存后自动生效

已登录的shell(已存在的进程)是不会自动更新的,当且仅当新生成的jiang用户的shell进程会获取配置中的最新限制作为自己的资源限制值。

我们在ulimit命令可以使用ulimited来作为一个资源的值,指代资源无限制。

但是我并未在/etc/security/limit.conf中找到类似ulimited的关键字…也就是说,我一定要给某个资源设置一个上限值?

例如,我给jiang用户设置CORE文件大小资源上限为1024KB(hard)。

我想要再次给jiang用户设置无限制无上限的值,不论是给其设置为0:

jiang hard core 0

或者注释掉这一行:

#jiang hard core 0

对于新创建的jiang的shell进程都是不起作用的,还是有一个上限值。

但是,当重启主机之后,似乎默认是jiang用户不设上限的CORE文件资源限制(hard):

[jiang@localhost ~]$ ulimit -Hc
unlimited
[jiang@localhost ~]$ ulimit -Sc
[jiang@localhost ~]$ ulimit -Hc unlimited
[jiang@localhost ~]$ ulimit -Hc
unlimited

有知道的小伙伴可以给我留言哈!我也多多学习下!

C/C++:进程资源限制函数(getrlimit、setrlimit)&amp;amp;&amp;amp; Shell-ulimit命令进程在操作系统内核中是一个独立存在的运行实体。每个进程都有 一组 资源限制,限制进程对于系统资源的申请量。可以通过 getrlimit 来获取当前进程某一指定资源的限制。可以通过 setrlimit 来设置当前进程某一指定资源的限制。进程的资源限制通常是在... 从静态存储区域 分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量 ,static变量 。 在栈 上创建。在执行函数时,函数内局部变量 的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。 从堆 上分配,亦称动态内存分配。程序在运行的时候用malloc 或new 申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内
1.getrlimit()/setrlimit()函数 获取或设置资源使用限制,linux下每种资源都有相关的软硬限制,软限制是内核强加给相应资源限制值,硬限制是软限制的最大值。非授权调用的进程只能将其软限制指定为0~硬限制范围中的某个值,同时能不可逆转地降低其硬限制。授权进程可以任意改变其软硬限制。RLIM_INFINITY:表示不对资源限制。 #include <sys/resource.h> int getrlimit(int resource, s
中,详细讲解了Linux系统对于每个进程资源限制(软限制于硬限制)管理机制。软限制是内核对相应资源强制执行的值。硬限制充当软限制的上限:无特权进程只能将其软限制设置为从。到硬限制的范围内的值,并且(不可逆转地)降低其硬限制。)设置shell资源限制shell资源限制由它为执行命令而创建的进程继承。每个资源都有一个相关联的软限制和硬限制,由。它可用于设置和获取任意进程资源限制。能力的进程)可以对任何一个限制值进行任意更改。来分别获取/设置系统的资源限制。创建的子进程继承其父进程资源限制
C++进程资源 什么是资源 资源进程执行任务过程中所使用的硬件设备或者软件材料,资源包括硬盘、RAM、CPU、打印机、显示器、键盘、网卡、文件、程序、数据、动态链接库等等。 资源可以是进程在任何给定时间使用的任何东西。 硬件资源 硬件资源是物理设备,例如CPU,进程使用它来进行数据操纵计算执行等等。此外还有内存RAM、外存ROM、非抢占式打印机、屏幕键盘鼠标等I/O设备。 这些I/O资源可以被多...
运行中的nginx进程间的关系 在正常环境下,部署nginx都是使用一个master进程来管理多个worker进程。一般情况下,worker进程的数量和服务器上的CPU核心数相等。 master进程只负责监控worker进程 worker进程提供服务。 默认情况下,nginx的运行目录为/usr/local/nginx $ tree ├── client_body_temp ├── conf │ ├── fastcgi.conf │ ├── fastcgi.conf.default
成员变量mData是存储数据的内存,mDataSize是数据的大小,mDataCapacity是存储内存的容量,mDataPos是数据的位置。 mObjects是为了保存Binder类对象使用的,mObjectsSize数据里面保存的Binder类对象的数量,mObjectsCapacity是内存中可以保存Binder类对象的大小容量。 成员变量mOwner是释放内存的方法,可能设置,也可能不设置。 ServiceManager IBinder b = ServiceManager.getServiceOr
每一个进程都用一组资源限值,它们可以用来限制进程能够消耗的各种系统资源。getrlimit()和setrlimit()系统调用允许一个进程读取和修改自己的资源限制,其函数原型如下: #include <sys/resource.h> int getrlimit(int resource,struct rlimit *rlim); int setrlimit(int resource,const struct rlimit *rlim); 成功返回0, 失败返回-1. 参数rlim用来