getrlimit() - Unix、Linux 系统调用
Tutorials Point


  Unix 初学者指南
  Unix Shell 编程
  高级 Unix
  Unix 有用参考
  Unix 有用资源
  精选阅读

版权所有 © 2014 tutorialspoint



  首页     参考     讨论论坛     关于 TP  

getrlimit() - Unix、Linux 系统调用


previous next AddThis Social Bookmark Button

广告

名称

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);

描述

getrlimit() 和 setrlimit() 分别获取和设置资源限制。每个资源都有一个关联的软限制和硬限制,如 rlimit 结构(getrlimit() 和 setrlimit() 的 rlim 参数)中所定义。

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

软限制是内核对相应资源执行的值。硬限制充当软限制的上限:非特权进程只能将其软限制设置为从 0 到硬限制范围内的值,并且(不可逆地)降低其硬限制。特权进程(在 Linux 中:具有 CAP_SYS_RESOURCE 能力的进程)可以对任一限制值进行任意更改。

RLIM_INFINITY 表示对资源没有限制(在 getrlimit() 返回的结构中以及传递给 setrlimit() 的结构中)。

resource 必须是以下之一:

标签描述
RLIMIT_AS
 进程虚拟内存(地址空间)的最大大小(以字节为单位)。此限制会影响对 brk(2)、mmap(2) 和 mremap(2) 的调用,这些调用在超出此限制时会失败并出现 ENOMEM 错误。此外,自动堆栈扩展也会失败(如果未通过 sigaltstack(2) 提供备用堆栈,则会生成一个终止进程的 SIGSEGV)。由于该值是 long 类型,因此在具有 32 位 long 的机器上,此限制最多为 2 GiB,或者此资源是无限的。
RLIMIT_CORE
 core 文件的最大大小。当为 0 时,不创建 core dump 文件。当不为零时,较大的 dump 将被截断到此大小。
RLIMIT_CPU
 CPU 时间限制(以秒为单位)。当进程达到软限制时,会向其发送 SIGXCPU 信号。此信号的默认操作是终止进程。但是,可以捕获该信号,并且处理程序可以将控制权返回到主程序。如果进程继续消耗 CPU 时间,则每秒钟会向其发送一次 SIGXCPU,直到达到硬限制,此时会向其发送 SIGKILL。(后一点描述了 Linux 2.2 到 2.6 的行为。实现方式在处理达到软限制后继续消耗 CPU 时间的进程方面有所不同。需要捕获此信号的可移植应用程序应在首次收到 SIGXCPU 时执行有序终止)。
RLIMIT_DATA
 进程数据段(已初始化数据、未初始化数据和堆)的最大大小。此限制会影响对 brk() 和 sbrk() 的调用,这些调用在遇到此资源的软限制时会失败并出现 ENOMEM 错误。
RLIMIT_FSIZE
 进程可以创建的文件的最大大小。尝试将文件扩展到此限制之外会导致发送 SIGXFSZ 信号。默认情况下,此信号会终止进程,但进程可以改为捕获此信号,在这种情况下,相关的系统调用(例如,write() truncate())会失败并出现 EFBIG 错误。
RLIMIT_LOCKS(仅限早期 Linux 2.4)
 对该进程可以建立的 flock() 锁和 fcntl() 租约的总数的限制。
RLIMIT_MEMLOCK
 可以锁定到 RAM 的内存字节的最大数量。实际上,此限制会向下舍入到最接近的系统页面大小的倍数。此限制会影响 mlock(2) 和 mlockall(2) 以及 mmap(2) MAP_LOCKED 操作。从 Linux 2.6.9 开始,它还会影响 shmctl(2) SHM_LOCK 操作,其中它为调用进程的真实用户 ID 可以锁定的共享内存段(请参阅 shmget(2))中的总字节数设置最大值。shmctl(2) SHM_LOCK 锁与 mlock(2)、mlockall(2) 和 mmap(2) MAP_LOCKED 建立的每个进程的内存锁分开计算;进程可以在这两个类别中的每个类别中锁定此限制范围内的字节数。在 2.6.9 之前的 Linux 内核中,此限制控制特权进程可以锁定的内存量。从 Linux 2.6.9 开始,对特权进程可以锁定的内存量没有限制,而此限制则控制非特权进程可以锁定的内存量。
RLIMIT_MSGQUEUE(自 Linux 2.6.8 起)
 指定可以为调用进程的真实用户 ID 分配的 POSIX 消息队列的字节数限制。此限制对 mq_open(3) 强制执行。用户创建的每个消息队列(直到将其删除)都会根据以下公式对此限制进行计算:

bytes = attr.mq_maxmsg * sizeof(struct msg_msg *) + attr.mq_maxmsg * attr.mq_msgsize

其中 attr 是作为 mq_open() 的第四个参数指定的 mq_attr 结构。

公式中的第一个加数(包括 sizeof(struct msg_msg *)(在 Linux/x86 上为 4 字节))确保用户不能创建无限数量的零长度消息(尽管如此,这些消息仍然会消耗一些系统内存用于簿记开销)。

RLIMIT_NICE(自内核 2.6.12 起,但请参阅下面的 BUG)
 指定可以使用 setpriority(2) 或 nice(2) 将进程的 nice 值提高到的上限。nice 值的实际上限计算为 20 - rlim_cur。(这种奇怪的情况发生是因为负数不能指定为资源限制值,因为它们通常具有特殊含义。例如,RLIM_INFINITY 通常与 -1 相同)。
RLIMIT_NOFILE
 指定一个值,该值比此进程可以打开的文件描述符号的最大值大 1。尝试(open()、pipe()、dup() 等)超过此限制会导致 EMFILE 错误。
RLIMIT_NPROC
 可以为调用进程的真实用户 ID 创建的线程的最大数量。遇到此限制时,fork() 会失败并出现 EAGAIN 错误。
RLIMIT_RSS
 指定进程驻留集(驻留在 RAM 中的虚拟页数)的限制(以页为单位)。此限制仅在 Linux 2.4.x(x < 30)中有效,并且仅影响指定 MADV_WILLNEEDmadvise() 调用。
RLIMIT_RTPRIO(自 Linux 2.6.12 起,但请参阅 BUG)
 指定可以使用 sched_setscheduler(2) 和 sched_setparam(2) 为此进程设置的实时优先级的上限。
RLIMIT_SIGPENDING(自 Linux 2.6.8 起)
 指定可以为调用进程的真实用户 ID 排队的信号数限制。标准信号和实时信号都计入检查此限制的目的。但是,此限制仅对 sigqueue(2) 强制执行;始终可以使用 kill(2) 来排队任何尚未排队到进程的信号的一个实例。
RLIMIT_STACK
 进程堆栈的最大大小(以字节为单位)。达到此限制时,会生成 SIGSEGV 信号。要处理此信号,进程必须使用备用信号堆栈(sigaltstack(2))。
RLIMIT_OFILERLIMIT_NOFILE 的 BSD 名称。

返回值

成功时,返回 0。错误时,返回 -1,并且 errno 设置为相应的值。

错误

标签描述
EFAULT rlim 指向可访问地址空间之外。
EINVAL resource 无效;或者,对于 setrlimit():rlim->rlim_cur 大于 rlim->rlim_max
EPERM 非特权进程尝试使用 setrlimit() 将软限制或硬限制提高到当前硬限制之上;需要 CAP_SYS_RESOURCE 能力才能执行此操作。或者,进程尝试使用 setrlimit() 将软限制或硬限制 RLIMIT_NOFILE 限制提高到当前内核最大值 (NR_OPEN) 以上。

BUG

在较旧的 Linux 内核中,当进程遇到软限制和硬限制 RLIMIT_CPU 限制时发送的 SIGXCPUSIGKILL 信号比应有的时间晚了一 (CPU) 秒。此问题已在内核 2.6.8 中修复。

在 2.6.x 内核(2.6.17 之前)中,0 的 RLIMIT_CPU 限制被错误地视为“无限制”(如 RLIM_INFINITY)。从内核 2.6.17 开始,设置 0 的限制确实会产生影响,但实际上被视为 1 秒的限制。

内核错误意味着 RLIMIT_RTPRIO 在内核 2.6.12 中不起作用;此问题已在内核 2.6.13 中修复。

在内核 2.6.12 中,getpriority(2) 和 RLIMIT_NICE 返回的优先级范围之间存在一个差 1 的不匹配。这导致 nice 值的实际上限计算为 19 - rlim_cur。此问题已在内核 2.6.13 中修复。

2.4.22 之前的内核未诊断 setrlimit() 的 EINVAL 错误,当时 rlim->rlim_cur 大于 rlim->rlim_max

注释

通过 fork(2) 创建的子进程继承其父进程的资源限制。资源限制在 execve(2) 中得以保留。

符合标准

SVr4、4.3BSD、POSIX.1-2001。RLIMIT_MEMLOCKRLIMIT_NPROC 源自 BSD,并且未在 POSIX.1-2001 中指定;它们存在于 BSD 和 Linux 上,但在其他一些实现中却很少见。RLIMIT_RSS 源自 BSD,并且未在 POSIX.1-2001 中指定;尽管如此,它仍然存在于大多数实现中。RLIMIT_MSGQUEUERLIMIT_NICERLIMIT_RTPRIORLIMIT_SIGPENDING 是 Linux 特定的。

参见



previous next Printer Friendly

广告


  

广告



广告