OJ设计细节 之 【进程资源限制】(getrlimit、setrlimit、prlimit)

目录

1.struct rlimit 

软限制 vs 硬限制

特殊值

不同资源类型的典型限制值

常用限制值参考

查看和设置命令

特殊说明

2. getrlimit() - 获取资源限制

3. setrlimit() - 设置资源限制

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_currlim_t软限制系统实际强制执行的限制值,进程可主动降低但通常不能提高
rlim_maxrlim_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_STACK8 MB无限字节栈空间大小防止栈溢出
RLIMIT_NOFILE10244096个数打开文件描述符数防止文件描述符泄漏
RLIMIT_NPROC无限无限个数进程/线程数防止 fork 炸弹
RLIMIT_FSIZE无限无限字节创建文件的最大大小限制输出文件大小
RLIMIT_CORE0无限字节core dump 文件大小控制调试信息(0=禁用)
RLIMIT_MEMLOCK64 KB64 KB字节锁定内存大小限制 mlock()/mlockall()
RLIMIT_SIGPENDING无限无限个数挂起信号队列长度限制信号队列堆积
RLIMIT_MSGQUEUE无限无限字节POSIX 消息队列大小限制 IPC 消息队列
RLIMIT_NICE00-nice 值限制限制进程优先级调整范围
RLIMIT_RTPRIO00-实时优先级限制限制实时进程优先级
RLIMIT_RTTIME无限无限微秒实时任务 CPU 时间限制实时任务执行时间
  • 在 Linux 下,RLIMIT_NPROC 限制的是每个真实用户 ID(UID)的进程和线程总数

资源限制信号表

resource超限时的信号默认行为说明
RLIMIT_CPUSIGXCPU终止进程超过软限制后每秒发送一次,达到硬限制时发送 SIGKILL
RLIMIT_ASSIGSEGV 或 SIGBUS终止进程内存分配失败时触发
RLIMIT_DATASIGSEGV 或 SIGBUS终止进程brk()/sbrk() 分配失败
RLIMIT_STACKSIGSEGV终止进程栈溢出时触发
RLIMIT_NOFILE无信号返回 EMFILEopen()/dup() 等返回错误
RLIMIT_NPROC无信号返回 EAGAINfork()/clone() 失败
RLIMIT_FSIZESIGXFSZ终止进程写入超过限制的文件
RLIMIT_CORE无信号不生成 core 文件setrlimit 后 RLIMIT_CORE=0 禁用 core dump
RLIMIT_MEMLOCK无信号返回 ENOMEMmlock()/mlockall() 失败
RLIMIT_SIGPENDING无信号返回 EAGAINsigpending() 队列满
RLIMIT_MSGQUEUE无信号返回 EAGAINmq_send() 失败
RLIMIT_NICE无信号返回 EPERMnice()/setpriority() 失败
RLIMIT_RTPRIO无信号返回 EPERMsched_setscheduler() 失败
RLIMIT_RTTIMESIGXCPU终止进程超过限制后收到 SIGXCPU

常用限制值参考

场景RLIMIT_CPURLIMIT_ASRLIMIT_STACKRLIMIT_NOFILE
在线判题系统1-10 秒256-512 MB64-128 MB100-200
Web 服务器无限无限8 MB65535
编译任务无限1-2 GB无限4096
后台服务无限无限8 MB1048576
Shell 环境无限无限8 MB1024

查看和设置命令

# 查看所有限制
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)
{ printf("软限制: %lu, 硬限制: %lu\n", rl.rlim_cur, rl.rlim_max);}

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);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值