目录
4. prlimit() - 进程资源限制查询/设置(扩展版)

各大OJ平台都会对用户提交的算法进行资源限制,下面详解进程资源限制接口
1.struct rlimit
#include <sys/resource.h>
struct rlimit {
rlim_t rlim_cur; /* 软限制 (soft limit) */
rlim_t rlim_max; /* 硬限制 (hard limit) */
};
| 成员 | 类型 | 说明 | 作用 |
|---|---|---|---|
rlim_cur | rlim_t | 软限制 | 系统实际强制执行的限制值,进程可主动降低但通常不能提高 |
rlim_max | rlim_t | 硬限制 | 软限制的上限值,只有特权进程才能提高 |
- rlim_t 类型
/* 通常定义为 unsigned long 或 unsigned long long */
typedef unsigned long rlim_t; /* 64位系统 */
- 取值范围:0 到 RLIM_INFINITY(通常为 -1UL 即 0xFFFFFFFFFFFFFFFF)
- RLIM_INFINITY 表示无限制
软限制 vs 硬限制
| 特性 | 软限制 (rlim_cur) | 硬限制 (rlim_max) |
|---|---|---|
| 当前生效值 | 是 | 仅作为上限 |
| 进程可修改范围 | 0 到 rlim_max | 只能降低(普通进程)或任意修改(root) |
| 非特权进程 | 可降低 | 只能降低到 ≥ 软限制 |
| 特权进程 (root) | 可任意设置 | 可任意设置 |
| 超限后果 | 触发限制行为 | 无直接作用 |
| 典型用途 | 实际约束进程 | 防止进程无限提高软限制 |
特殊值
| 宏 | 值 | 含义 |
|---|---|---|
RLIM_INFINITY | -1UL (0xFFFFFFFFFFFFFFFF) | 无限制 |
不同资源类型的典型限制值
| resource | 典型软限制 | 典型硬限制 | 单位 | 说明 | 典型用途 |
|---|---|---|---|---|---|
RLIMIT_CPU | 无限 | 无限 | 秒 | CPU 时间限制 | 防止死循环耗尽 CPU |
RLIMIT_AS | 无限 | 无限 | 字节 | 进程总虚拟内存 | 防止内存泄漏 |
RLIMIT_DATA | 无限 | 无限 | 字节 | 数据段+堆内存 | 限制动态内存分配 |
RLIMIT_STACK | 8 MB | 无限 | 字节 | 栈空间大小 | 防止栈溢出 |
RLIMIT_NOFILE | 1024 | 4096 | 个数 | 打开文件描述符数 | 防止文件描述符泄漏 |
RLIMIT_NPROC | 无限 | 无限 | 个数 | 进程/线程数 | 防止 fork 炸弹 |
RLIMIT_FSIZE | 无限 | 无限 | 字节 | 创建文件的最大大小 | 限制输出文件大小 |
RLIMIT_CORE | 0 | 无限 | 字节 | core dump 文件大小 | 控制调试信息(0=禁用) |
RLIMIT_MEMLOCK | 64 KB | 64 KB | 字节 | 锁定内存大小 | 限制 mlock()/mlockall() |
RLIMIT_SIGPENDING | 无限 | 无限 | 个数 | 挂起信号队列长度 | 限制信号队列堆积 |
RLIMIT_MSGQUEUE | 无限 | 无限 | 字节 | POSIX 消息队列大小 | 限制 IPC 消息队列 |
RLIMIT_NICE | 0 | 0 | - | nice 值限制 | 限制进程优先级调整范围 |
RLIMIT_RTPRIO | 0 | 0 | - | 实时优先级限制 | 限制实时进程优先级 |
RLIMIT_RTTIME | 无限 | 无限 | 微秒 | 实时任务 CPU 时间 | 限制实时任务执行时间 |
- 在 Linux 下,RLIMIT_NPROC 限制的是每个真实用户 ID(UID)的进程和线程总数
资源限制信号表
| resource | 超限时的信号 | 默认行为 | 说明 |
|---|---|---|---|
RLIMIT_CPU | SIGXCPU | 终止进程 | 超过软限制后每秒发送一次,达到硬限制时发送 SIGKILL |
RLIMIT_AS | SIGSEGV 或 SIGBUS | 终止进程 | 内存分配失败时触发 |
RLIMIT_DATA | SIGSEGV 或 SIGBUS | 终止进程 | brk()/sbrk() 分配失败 |
RLIMIT_STACK | SIGSEGV | 终止进程 | 栈溢出时触发 |
RLIMIT_NOFILE | 无信号 | 返回 EMFILE | open()/dup() 等返回错误 |
RLIMIT_NPROC | 无信号 | 返回 EAGAIN | fork()/clone() 失败 |
RLIMIT_FSIZE | SIGXFSZ | 终止进程 | 写入超过限制的文件 |
RLIMIT_CORE | 无信号 | 不生成 core 文件 | setrlimit 后 RLIMIT_CORE=0 禁用 core dump |
RLIMIT_MEMLOCK | 无信号 | 返回 ENOMEM | mlock()/mlockall() 失败 |
RLIMIT_SIGPENDING | 无信号 | 返回 EAGAIN | sigpending() 队列满 |
RLIMIT_MSGQUEUE | 无信号 | 返回 EAGAIN | mq_send() 失败 |
RLIMIT_NICE | 无信号 | 返回 EPERM | nice()/setpriority() 失败 |
RLIMIT_RTPRIO | 无信号 | 返回 EPERM | sched_setscheduler() 失败 |
RLIMIT_RTTIME | SIGXCPU | 终止进程 | 超过限制后收到 SIGXCPU |
常用限制值参考
| 场景 | RLIMIT_CPU | RLIMIT_AS | RLIMIT_STACK | RLIMIT_NOFILE |
|---|---|---|---|---|
| 在线判题系统 | 1-10 秒 | 256-512 MB | 64-128 MB | 100-200 |
| Web 服务器 | 无限 | 无限 | 8 MB | 65535 |
| 编译任务 | 无限 | 1-2 GB | 无限 | 4096 |
| 后台服务 | 无限 | 无限 | 8 MB | 1048576 |
| Shell 环境 | 无限 | 无限 | 8 MB | 1024 |
查看和设置命令
# 查看所有限制
ulimit -a
# 查看单项
ulimit -t # CPU time (seconds)
ulimit -v # virtual memory (KB)
ulimit -s # stack size (KB)
ulimit -n # open files
ulimit -u # processes
ulimit -c # core dump size (blocks)
# 设置限制
ulimit -t 10 # CPU 时间限制 10 秒
ulimit -v 524288 # 虚拟内存限制 512 MB
ulimit -n 2048 # 文件描述符限制 2048
2. getrlimit() - 获取资源限制
| 项目 | 说明 |
|---|---|
| 函数原型 | int getrlimit(int resource, struct rlimit *rlim); |
| 功能 | 获取指定资源的当前软限制和硬限制 |
| 参数 resource | 资源类型(见上表) |
| 参数 rlim | 输出参数,返回限制值 |
| 返回值 | 成功返回 0,失败返回 -1 |
| 错误码 | EFAULT:rlim 指针无效EINVAL:resource 无效EPERM:权限不足 |
| 结构体定义 | struct rlimit { rlim_t rlim_cur; // 软限制 rlim_t rlim_max; // 硬限制}; |
| 使用示例 | struct rlimit rl; if (getrlimit(RLIMIT_NOFILE, &rl) == 0) |
3. setrlimit() - 设置资源限制
| 项目 | 说明 |
|---|---|
| 函数原型 | int setrlimit(int resource, const struct rlimit *rlim); |
| 功能 | 设置指定资源的软限制和硬限制 |
| 参数 resource | 资源类型(见上表) |
| 参数 rlim | 输入参数,指定新的限制值 |
| 返回值 | 成功返回 0,失败返回 -1 |
| 错误码 | EFAULT:rlim 指针无效EINVAL:resource 无效或限制值无效EPERM:无权提高硬限制ESRCH:进程不存在(仅限 prlimit) |
| 重要规则 | ① 普通进程只能降低硬限制 ② 软限制 ≤ 硬限制 ③ 子进程继承父进程限制 ④ root 可任意设置 |
| 使用示例 | struct rlimit rl; rl.rlim_cur = 1024; // 软限制 rl.rlim_max = 2048; // 硬限制 if (setrlimit(RLIMIT_NOFILE, &rl) == -1) { perror("setrlimit failed");} |
4. prlimit() - 进程资源限制查询/设置
| 项目 | 说明 |
|---|---|
| 函数原型 | int prlimit(pid_t pid, int resource, const struct rlimit *new_limit, struct rlimit *old_limit); |
| 功能 | 查询或设置任意进程的资源限制(Linux 特有) |
| 参数 pid | 目标进程 PID: • 0:调用进程自身• >0:指定进程• -1:未定义(不可用) |
| 参数 resource | 资源类型(见上表) |
| 参数 new_limit | 新限制(设置为 NULL 表示仅查询) |
| 参数 old_limit | 旧限制(若不为 NULL,返回原值) |
| 返回值 | 成功返回 0,失败返回 -1 |
| 权限要求 | ① 同用户:可查询和降低限制 ② root:可任意修改 ③ 需要 CAP_SYS_RESOURCE 能力 |
| 优势 | ① 原子操作(查询+设置) ② 可操作其他进程 ③ 避免竞态条件 |
| 使用示例 | // 仅查询其他进程 struct rlimit old; prlimit(target_pid, RLIMIT_AS, NULL, &old);// 设置并获取旧值(原子操作) struct rlimit new = {1024*1024, 1024*1024}; struct rlimit old; prlimit(0, RLIMIT_AS, &new, &old); |
&spm=1001.2101.3001.5002&articleId=161088408&d=1&t=3&u=c105315dcaff498dad58490184f92c49)

被折叠的 条评论
为什么被折叠?



