在Linux中每个进程都有一组资源限制,其中一些可以通过下列函数进行查询和更改:
#include <sys/resource.h>
#include <sys/time.h>
int getrlimit(int resource,struct rlimit *rlptr);
int setrlimit(int resource,struct rlimit *rlptr);
两个函数的返回值:若成功,返回0;若出错,返回-1,并设置相应的errno
其中rlimit结构体为
struct rlimit
{
rlim_t rlim_cur; //rlim_cur为指定的资源指定当前的系统软限制
rlim_t rlim_max; //rlim_max为指定的资源指定当前的系统硬限制
};
第一个参数为资源类型
资源限制类型概要描述如下:
- RLIMIT_CORE
core文件的最大字节数,若其值为0则阻止创建core文件。
- RLIMIT_CPU
CPU时间的最大量值(秒),当超过此软限制时,向该进程发送S I G X C P U信号。
- RLIMIT_DATA
一个进程的数据段最大字节长度。数据段中初始化数据、非初始化数据以及堆的总和。当调用函数brk动态改变一个进程的数据段大小时,若失败,errno值将被设置为ENOMEM。
- RLIMIT_FSIZE
可以创建的文件的最大字节长度。当超过此软限制时,则向该进程发送SIGXFSZ信号。
- RLIMIT_NOFILE
每个进程能打开的最多文件数。
- RLIMIT_STACK
栈的最大字节长度。系统不会动态增加栈的大小限制。
在进程内部,setrlimit()将增加限制以适合您的栈大小,而不会移动当前内存段来允许增长。为了保证进程的栈能够增长,限制必须首先改变以适应运行进程使用的新栈大小。
在一个多线程的进程中,若在线程中调用setrlimit(),而该线程不是主线程,则对于栈的限制没有任何改变。使用参数RLIMIT_STACK来调用setrlimit()仅仅能够影响主线程的栈,并且该工作本来就应该由主线程来完成。
当超越栈大小限制时,信号SIGSEGV会发给进程。如果进程忽略该信号,或者捕捉该信号但是没有设置处理措施,该信号默认设置为SIG_DFL处理方案。
- RLIMIT_VMEM
可映照地址空间的最大字节长度(和RLIMIT_AS相同)。
- RLIMIT_AS
进程可用内存最大字节数。
- 使用注意
当设置RLIMIT_DATA时,如果被接受,malloc函数可能失败,并设置errno为ENOMEM。
在Linux中,使用mmap()分配的内存不再计入数据段中,而sbrk()和brk()分配的内存才是数据段的一部分。最近的POSIX.1不再指定brk(),许多操作系统也不再将brk()作为系统调用,而是用mmap()替换。最新版的glibc使用mmap()实现malloc内存分配,所以RLIMIT_DATA限制对glibc的malloc函数没有作用。
因此,如果需要限制动态内存分配,设置RLIMIT_AS限制即可。