第 36 章 进程资源 (Process Resources)

      +

      核心结论

      • getrusage() 取资源使用统计:RUSAGE_SELF/CHILDREN/THREAD(Linux 2.6.26+);rusage 结构含 user/system CPU time、page faults、context switches、max RSS、block I/O 等(部分字段 Linux 未实现)。

      • setrlimit/getrlimit 设/取资源限制:每资源有 soft(实际)+ hard(上限)两值;soft 0 到 hard 之间可任意调;非特权只能降低 hard(irreversibly);RLIM_INFINITY = 无限制;fork 继承、exec 保留。

      • RLIMIT_NPROC 限制 per-UID 进程数:基于 real UID 计数(同 UID 所有进程合计);fork/vfork/clone 超限 → EAGAIN;不影响特权进程(CAP_SYS_ADMIN 或 CAP_SYS_RESOURCE);其实是「per-UID 线程数」。

      • RLIMIT_NOFILE 限制 fd 数:值为「最大 fd 号 + 1」;open/pipe/socket/accept/dup 等超限 → EMFILE(dup2 EBADF,fcntl F_DUPFD EINVAL);硬上限 NR_OPEN = 1048576(2.6.25 前硬编码,后 /proc/sys/fs/nr_open)。

      • RLIMIT_CPU 限制 CPU 时间(秒):达 soft → SIGXCPU(每秒一次),hard → SIGKILL(不可 catch);默认值 = RLIM_INFINITY;用于防 runaway 进程。

      • RLIMIT_FSIZE 限制文件大小:write/truncate 超限 → SIGXFSZ + EFBIG;默认 RLIM_INFINITY;RLIMIT_CORE 0 可禁止 core dump。

      • Linux 特有 RLIMIT_NICE/RLIMIT_RTPRIO/RLIMIT_RTTIME/RLIMIT_MSGQUEUE/RLIMIT_SIGPENDING/RLIMIT_MEMLOCK:分别限制 nice 上限、实时优先级上限、实时 CPU 时间(μs)、POSIX 消息队列字节数、per-UID 排队信号数、可锁内存字节数。

      本章主旨

      本章深入进程资源使用统计与限制——getrusage 监控自身/子进程资源消耗;setrlimit/getrlimit 控制进程可消耗的资源上限。读者应掌握:rusage 字段含义(哪些 Linux 实现了、哪些未实现)、rlimit 结构(soft/hard + RLIM_INFINITY)、各 RLIMIT_* 资源限制的含义与单位(虚拟内存、文件大小、CPU、fd 数、per-UID 进程数、栈大小等)、soft 达限行为(信号 vs 系统调用失败)、Linux 特有 RLIMIT_*(NICE/RTPRIO/RTTIME/MSGQUEUE/SIGPENDING/MEMLOCK)。理解「资源限制是 per-process 但有时 per-UID 累计」(RLIMIT_NPROC 是 per-UID)是写 fork bomb 防御、资源监控、daemon 资源隔离的关键。

      一、核心概念

      本章围绕 6 个核心概念展开:从 getrusage 资源统计入手,到 rlimit 软硬限制、各 RLIMIT_* 资源(标准 + Linux 特有)、资源限制的 per-process vs per-UID 语义、信号触发与系统调用失败。

      概念 定义 + 重要性 实现提示

      getrusage() 资源使用统计

      取资源使用(who: RUSAGE_SELF/CHILDREN/THREAD);rusage 结构含 ru_utime/stime/ru_maxrss/ru_minflt/ru_majflt/ru_inblock/ru_oublock/ru_nvcsw/ru_nivcsw 等;多数 ru_*ixrss 字段 Linux 未用。

      §36.1;RUSAGE_CHILDREN 包含所有 wait() 过的子进程(含 grandchild 在子 wait 后算到子,子 wait 后算到父);2.6.26+ RUSAGE_THREAD 线程级。

      rlimit 软硬限制结构

      struct rlimit { rlim_cur (soft); rlim_max (hard) };soft 0-hard 间可调;hard 非特权只能降低;特权(CAP_SYS_RESOURCE)可双向调(hard ≥ soft);RLIM_INFINITY 表示无限;fork 继承、exec 保留。

      §36.2;rlim_t 整数类型(通常同 off_t);RLIM_SAVED_CUR/MAX 表示不可表示(Linux 上等同 RLIM_INFINITY);x86-32 大文件编译环境下 setrlimit 超 32-bit unsigned long → RLIM_INFINITY。

      RLIMIT_NPROC per-UID 进程数限制

      限制 per-real-UID 的进程/线程数;超限 fork/vfork/clone → EAGAIN;同 UID 所有进程合计计数;不影响 CAP_SYS_ADMIN/CAP_SYS_RESOURCE 特权进程;Linux 上其实限制「线程数」。

      §36.3;/proc/sys/kernel/threads-max 系统级;默认根据物理内存计算;RLIMIT_NPROC 不影响其他 UID 的进程;sysconf(_SC_CHILD_MAX) 2.6.23+ 准确(之前返回 999)。

      RLIMIT_CPU/FSIZE/CORE 信号触发限制

      RLIMIT_CPU(秒):达 soft → SIGXCPU(每秒一次),hard → SIGKILL;handler 可清理后退出。RLIMIT_FSIZE(字节):write/truncate 超限 → SIGXFSZ + EFBIG。RLIMIT_CORE(字节):core dump 上限;0 = 禁止 core dump。

      §36.3;默认值 RLIM_INFINITY;用于防 runaway;handler 后建议退出(避免无限 SIGXCPU);用 ulimit -c 0 禁用 core dump(生产环境)。

      RLIMIT_NOFILE / RLIMIT_AS / RLIMIT_STACK / RLIMIT_DATA

      RLIMIT_NOFILE:max fd + 1;open 超限 EMFILE(dup2 EBADF,fcntl F_DUPFD EINVAL);上限 NR_OPEN = 1048576(2.6.25+ /proc/sys/fs/nr_open)。RLIMIT_AS:虚拟内存字节数;超限 ENOMEM。RLIMIT_STACK:栈字节数;超限 SIGSEGV(需 alternate stack)。

      §36.3;sysconf(_SC_OPEN_MAX) 与 RLIMIT_NOFILE 同步(Linux);/proc/sys/fs/file-max 系统级 fd 数;ulimit -n 改 RLIMIT_NOFILE。

      Linux 特有 RLIMIT_NICE/RTPRIO/RTTIME/MSGQUEUE/SIGPENDING/MEMLOCK

      RLIMIT_NICE(2.6.12+):nice 上限 = 20 - rlim_cur;非特权设实时策略。RLIMIT_RTPRIO(2.6.12+):实时优先级上限。RLIMIT_RTTIME(2.6.25+):实时进程连续 CPU 时间(μs)→ SIGXCPU/SIGKILL。RLIMIT_MSGQUEUE:per-UID POSIX 消息队列字节数。RLIMIT_SIGPENDING:per-UID 排队信号数。RLIMIT_MEMLOCK:可锁内存字节数(mlock)。

      §36.3;与第 35 章调度、信号、内存锁章节交叉;详见各章节。

      二、详细笔记

      36.1 getrusage() 资源使用统计

      Whatgetrusage(who, &ru) 取进程资源使用统计;who 决定 SELF/CHILDREN/THREAD。

      Why:监控进程 CPU/内存/I/O/上下文切换消耗;写 time(1) 类似的资源监控工具;监控子进程累计资源。

      How

      // 摘自《The Linux Programming Interface》第 36 章
      #include <sys/resource.h>
      int getrusage(int who, struct rusage *res_usage);

      who 取值:

      • RUSAGE_SELF:调用进程。

      • RUSAGE_CHILDREN:所有已 wait 的子进程(含 grandchild 链)。

      • RUSAGE_THREAD(Linux 2.6.26+):调用线程。

      rusage 字段(§36.1):

      字段 含义 Linux 状态

      ru_utime

      user CPU time

      ru_stime

      system CPU time

      ru_maxrss

      最大驻留集大小(KB)

      ✓ (2.6.32+)

      ru_minflt

      minor page fault(无需 I/O)

      ru_majflt

      major page fault(需 I/O)

      ru_inblock

      块设备读操作

      ✓ (2.6.22+)

      ru_oublock

      块设备写操作

      ✓ (2.6.22+)

      ru_nvcsw

      voluntary context switch

      ✓ (2.6+)

      ru_nivcsw

      involuntary context switch

      ✓ (2.6+)

      ru_ixrss/idrss/isrss

      积分共享/数据/栈内存

      ✗ unused

      ru_nswap

      swap 次数

      ✗ unused

      ru_msgsnd/msgrcv

      IPC 消息计数

      ✗ unused

      ru_nsignals

      收到信号数

      ✗ unused

      RUSAGE_CHILDREN 累加规则(§36.1):

      • 子 wait 自己的 child → 累加到子 RUSAGE_CHILDREN。

      • 父 wait 子 → 子 + grandchild 都累加到父 RUSAGE_CHILDREN。

      • 子不 wait grandchild → grandchild 不计入父。

      • ru_maxrss 是所有 descendant 的最大值(不是总和)。

      • SIGCHLD = SIG_IGN 不 wait → 资源丢失(2.6.9 之前 Linux 偏离 SUSv3 计入;之后符合)。

      When:写 time(1) 工具;监控子进程资源;性能调优时看 page fault / context switch。

      Example

      // 摘自《The Linux Programming Interface》第 36 章
      struct rusage ru;
      getrusage(RUSAGE_SELF, &ru);
      printf("user CPU: %ld.%06ld, sys CPU: %ld.%06ld\n",
             ru.ru_utime.tv_sec, ru.ru_utime.tv_usec,
             ru.ru_stime.tv_sec, ru.ru_stime.tv_usec);
      printf("page faults: min=%ld maj=%ld\n", ru.ru_minflt, ru.ru_majflt);
      printf("context switches: vol=%ld invol=%ld\n", ru.ru_nvcsw, ru.ru_nivcsw);

      36.2 setrlimit/getrlimit 资源限制

      What:每个进程有 rlimit 表(每资源 soft + hard);setrlimit 改、getrlimit 查;限制进程可消耗的资源。

      Why:防止进程消耗过多资源(CPU、内存、fd、文件大小);set-UID 程序在 exec 前重置资源限制;fork bomb 防御。

      How

      // 摘自《The Linux Programming Interface》第 36 章
      #include <sys/resource.h>
      struct rlimit { rlim_t rlim_cur; rlim_t rlim_max; };
      int getrlimit(int resource, struct rlimit *rlim);
      int setrlimit(int resource, const struct rlimit *rlim);

      rlimit 结构(§36.2):

      • rlim_cur:soft 限制(实际生效值)。

      • rlim_max:hard 限制(rlim_cur 的上限,ceil)。

      • RLIM_INFINITY:无限制(特殊值)。

      权限规则:

      • 非特权:soft 可任意调(0-hard);hard 只能降低(irreversibly);不能增加。

      • 特权(CAP_SYS_RESOURCE):hard 可双向调(必须 ≥ soft)。

      • 行为:soft 限制达限 → 信号 或 系统调用失败。

      资源限制 vs 进程 vs UID(§36.2):

      • 多数限制:per-process(只影响本进程)。

      • RLIMIT_NPROC/RLIMIT_MSGQUEUE/RLIMIT_SIGPENDING:per-real-UID(所有同 UID 进程合计)。

      • 限制检查:进程及其 descendants(继承限制的);同 UID 其他进程不受影响(除非它们也设了)。

      未表示限制值(§36.2):

      • RLIM_SAVED_CUR/RLIM_SAVED_MAX:表示 rlim_t 无法表示的限制值。

      • Linux:定义为 RLIM_INFINITY(所有值可表示)。

      • x86-32 + 大文件编译:setrlimit 超 32-bit unsigned long → 静默转 RLIM_INFINITY(问题)。

      shell 命令 vs getrlimit 单位(§36.2):

      • bash ulimit / ksh ulimit / csh limit:单位可能与系统调用不同(如栈大小用 KB)。

      • 建议:直接用 getrlimit/setrlimit 编程。

      When:写 set-UID wrapper 程序(exec 前重置资源);fork bomb 防御(设 RLIMIT_NPROC);debug 资源问题;生产环境 RLIMIT_CORE=0。

      Example(§36.2):

      // 摘自《The Linux Programming Interface》第 36 章 — printRlimit 简化版
      int printRlimit(const char *msg, int resource) {
          struct rlimit rlim;
          getrlimit(resource, &rlim);
          printf("%s soft=%s; hard=%s\n", msg,
                 rlim.rlim_cur == RLIM_INFINITY ? "inf" :
                 (char *)(long long)rlim.rlim_cur,
                 rlim.rlim_max == RLIM_INFINITY ? "inf" :
                 (char *)(long long)rlim.rlim_max);
      }

      36.3 各 RLIMIT_* 资源详解

      What:每个具体资源限制的含义、单位、达限行为、Linux 特有性。

      Why:理解每个 RLIMIT 的语义是写资源受限程序的基础。

      How

      标准 RLIMIT_*(§36.3):

      限制 含义 达限行为

      RLIMIT_AS

      进程虚拟内存(字节)

      brk/sbrk/mmap/mremap/shmat → ENOMEM

      RLIMIT_CORE

      core dump 文件大小(字节)

      0 = 禁止 core dump

      RLIMIT_CPU

      CPU 时间(秒,user + sys)

      达 soft → SIGXCPU(每秒);达 hard → SIGKILL

      RLIMIT_DATA

      数据段(init+bss+heap,字节)

      sbrk/brk → ENOMEM

      RLIMIT_FSIZE

      文件大小(字节)

      write/truncate → SIGXFSZ + EFBIG

      RLIMIT_NOFILE

      最大 fd 号 + 1

      open/pipe/…​ → EMFILE;dup2 → EBADF;fcntl F_DUPFD → EINVAL

      RLIMIT_STACK

      栈大小(字节)

      栈增长 → SIGSEGV(需 alternate signal stack catch)

      Linux 特有 RLIMIT_*(§36.3):

      限制 含义 达限行为 引入版本

      RLIMIT_MEMLOCK

      可锁内存字节数(mlock/mlockall)

      mlock → ENOMEM

      BSD-derived

      RLIMIT_MSGQUEUE

      per-UID POSIX 消息队列字节数

      mq_open → EAGAIN

      2.6.8

      RLIMIT_NICE

      nice 上限 = 20 - rlim_cur

      nice/sched_setscheduler 受限

      2.6.12

      RLIMIT_NPROC

      per-UID 进程/线程数

      fork/vfork/clone → EAGAIN

      BSD-derived

      RLIMIT_RSS

      驻留集大小(页面数)

      未实现

      BSD-derived

      RLIMIT_RTPRIO

      实时优先级上限

      sched_setscheduler/setparam 受限

      2.6.12

      RLIMIT_RTTIME

      实时 CPU 时间(μs)连续不阻塞

      达 soft → SIGXCPU;达 hard → SIGKILL

      2.6.25

      RLIMIT_SIGPENDING

      per-UID 排队信号数

      sigqueue → EAGAIN

      2.6.8

      系统级限制(§36.3):

      • /proc/sys/fs/file-max:系统级最大 open file description 数;超限 ENFILE;CAP_SYS_ADMIN 可超过。

      • /proc/sys/fs/nr_open(2.6.25+):RLIMIT_NOFILE 硬上限(默认 1048576)。

      • /proc/sys/kernel/threads-max:系统级最大线程数(2.4+)。

      RLIMIT_CPU 详细(§36.3):

      • 软限制达:SIGXCPU 信号,默认动作 = 终止 + core dump。

      • handler 可清理资源后退出;建议首次收到就退出(避免持续 SIGXCPU)。

      • Linux:handler 返回后 SIGXCPU 每秒一次;达硬限制 → SIGKILL(不可 catch)。

      • 移植性:多数 UNIX 持续 SIGXCPU 直到退出或 setrlimit 调整。

      RLIMIT_STACK 详细(§36.3):

      • 栈增长超限 → SIGSEGV。

      • 因栈耗尽,handler 只能在 alternate signal stack 运行(sigaltstack,§21.3)。

      • 2.6.23+ RLIMIT_STACK 还限制命令行参数 + 环境变量总大小。

      RLIMIT_NPROC 详细(§36.3):

      • 限制 per-real-UID 的线程数(不是进程)。

      • 不影响 CAP_SYS_ADMIN/CAP_SYS_RESOURCE 特权进程。

      • 默认值:2.2 固定公式;2.4+ 基于物理内存。

      • sysconf(_SC_CHILD_MAX):2.6.23+ 准确(之前总是返回 999)。

      RLIMIT_RSS 详细(§36.3):

      • Linux 上未实现——存在但无效果。

      • 旧 2.4(≤2.4.29)影响 madvise MADV_WILLNEED → EIO。

      RLIMIT_SIGPENDING 详细(§36.3):

      • 仅 sigqueue 受限(kill 不受限——可入队 1 实例/信号/进程)。

      • 默认 1024(初始)→ 2.6.12+ 同 RLIMIT_NPROC。

      • /proc/PID/status SigQ 字段显示当前排队信号数。

      When:见每个 RLIMIT 的应用场景——CPU 限制防 runaway;fd 数限制防 fd exhaustion;per-UID 进程数防 fork bomb;MLOCK 限制防内存锁滥用。

      Example(§36.3):

      // 摘自《The Linux Programming Interface》第 36 章 — Listing 36-3
      // 摘自 procres/rlimit_nproc.c
      struct rlimit rl;
      rl.rlim_cur = getInt(argv[1], 0, "soft-limit");
      rl.rlim_max = (argc == 2) ? rl.rlim_cur : getInt(argv[2], 0, "hard-limit");
      setrlimit(RLIMIT_NPROC, &rl);
      /* 接下来 fork 直到 EAGAIN */
      for (;;) {
          pid_t pid = fork();
          if (pid == -1) { /* EAGAIN */
              perror("fork");
              break;
          }
          /* 子立即 _exit */
      }

      三、关键图表

      标准 + Linux 特有 RLIMIT 一览(表 36-1)
      资源 限制内容 达限行为 SUSv3/版本

      RLIMIT_AS

      虚拟内存字节数

      brk/sbrk/mmap → ENOMEM

      SUSv3

      RLIMIT_CORE

      core dump 字节数

      限制 core 大小;0 = 禁止

      SUSv3

      RLIMIT_CPU

      CPU 时间秒

      SIGXCPU(每秒)→ SIGKILL

      SUSv3

      RLIMIT_DATA

      数据段字节数

      sbrk → ENOMEM

      SUSv3

      RLIMIT_FSIZE

      文件大小字节数

      SIGXFSZ + EFBIG

      SUSv3

      RLIMIT_MEMLOCK

      可锁内存字节数

      mlock → ENOMEM

      BSD (无 SUSv3)

      RLIMIT_MSGQUEUE

      per-UID POSIX MQ 字节数

      mq_open → EAGAIN

      2.6.8

      RLIMIT_NICE

      nice 上限

      nice/sched_setscheduler 受限

      2.6.12

      RLIMIT_NOFILE

      最大 fd 号 + 1

      open → EMFILE

      SUSv3

      RLIMIT_NPROC

      per-UID 线程数

      fork/clone → EAGAIN

      BSD (无 SUSv3)

      RLIMIT_RSS

      驻留集页面数

      Linux 未实现

      BSD (无 SUSv3)

      RLIMIT_RTPRIO

      实时优先级上限

      sched_setscheduler 受限

      2.6.12

      RLIMIT_RTTIME

      实时 CPU 时间 μs

      SIGXCPU → SIGKILL

      2.6.25

      RLIMIT_SIGPENDING

      per-UID 排队信号数

      sigqueue → EAGAIN

      2.6.8

      RLIMIT_STACK

      栈字节数

      栈增长 → SIGSEGV

      SUSv3

      rlimit 权限规则
      操作 非特权 特权 (CAP_SYS_RESOURCE)

      soft 限制 0-hard 范围

      ✓ 任意调

      ✓ 任意调

      hard 限制上调

      ✓ 必须 ≥ soft

      hard 限制下调

      ✓ irreversibly

      rusage 字段 Linux 状态
      字段 含义 Linux 实现

      ru_utime

      user CPU

      ru_stime

      system CPU

      ru_maxrss

      max RSS (KB)

      ✓ (2.6.32+)

      ru_minflt / ru_majflt

      minor/major page faults

      ru_inblock / ru_oublock

      块设备 I/O 操作

      ✓ (2.6.22+)

      ru_nvcsw / ru_nivcsw

      自愿/非自愿 context switch

      ✓ (2.6+)

      ru_ixrss / ru_idrss / ru_isrss

      积分内存(KB-秒)

      ✗ unused

      ru_nswap

      swap 次数

      ✗ unused

      ru_msgsnd / ru_msgrcv

      IPC 消息

      ✗ unused

      ru_nsignals

      收到信号数

      ✗ unused

      四、思维导图

      mindmap
        root((第 36 章 进程资源))
          getrusage
            RUSAGE SELF CHILDREN THREAD
            rusage 结构
            utime stime CPU
            maxrss 2 6 32
            page faults min maj
            block I/O 2 6 22
            context switch vol invol
            ixrss idrss 未用
            RUSAGE CHILDREN 累加
          rlimit 结构
            rlim cur soft
            rlim max hard
            RLIM INFINITY
            0 hard 范围
            非特权只能降 hard
            CAP SYS RESOURCE
            fork 继承 exec 保留
            RLIM SAVED CUR MAX
            x86 32 大文件问题
          RLIMIT 详解
            AS 虚拟内存
            CORE core dump 0
            CPU 秒 SIGXCPU KILL
            DATA 数据段
            FSIZE 文件 SIGXFSZ
            NOFILE max fd 1
            EMFILE EBADF EINVAL
            STACK 栈 SIGSEGV
            alternate stack
            命令行参数上限 2 6 23
          Linux 特有 RLIMIT
            NPROC per UID 线程
            EAGAIN
            CAP SYS ADMIN 例外
            threads max 系统级
            NICE 20 rlim cur
            RTPRIO 实时优先级
            RTTIME 实时 CPU 微秒
            SIGXCPU SIGKILL
            MSGQUEUE per UID
            SIGPENDING per UID
            sigqueue EAGAIN
            kill 不受限
            MEMLOCK mlock
            RSS 未实现
          系统级限制
            file max open fd 数
            nr open NOFILE 上限
            1048576 默认
            threads max 线程数
            CAP SYS ADMIN 超 file max
            ENFILE
          应用
            fork bomb 防御 NPROC
            set UID 重置限制
            防止 runaway CPU
            生产 CORE 0
            内存锁定上限

      五、重点与易错点

      1. getrusage RUSAGE_CHILDREN 只含已 wait 的子:未 wait 的 child/grandchild 不计入;这是 wait 后才能回收子状态的副作用。

      2. RLIMIT_NPROC 是 per-real-UID 线程数:不是 per-process;同 UID 所有进程合计计数;限制检查:进程及其 descendants(继承限制的)。

      3. RLIMIT_NPROC 不影响特权进程(CAP_SYS_ADMIN 或 CAP_SYS_RESOURCE);fork bomb 防御不能依赖此限制。

      4. rlimit soft 是实际生效值;hard 是 ceiling;非特权只能降低 hard(irreversibly);特权可双向调但必须 soft ≤ hard。

      5. RLIM_INFINITY 是特殊值:表示无限;getrlimit 返回时无限制 → RLIM_INFINITY;setrlimit 接受 RLIM_INFINITY 表示设无限。

      6. x86-32 + 大文件编译(_FILE_OFFSET_BITS=64):setrlimit 超 32-bit unsigned long → 静默转 RLIM_INFINITY——glibc 的 workaround;程序不会报错。

      7. RLIMIT_CPU 达 soft → SIGXCPU(每秒一次);达 hard → SIGKILL(不可 catch);handler 后建议立即退出。

      8. RLIMIT_FSIZE 达限 → SIGXFSZ + EFBIG;write/truncate 失败;handler 后续 write 仍触发(持续 SIGXFSZ)。

      9. RLIMIT_NOFILE 限制「最大 fd 号 + 1」——不是 fd 数;默认值通常 1024;硬上限 NR_OPEN = 1048576(2.6.25 前硬编码,后 /proc/sys/fs/nr_open)。

      10. RLIMIT_STACK 达限 → SIGSEGV——因栈耗尽只能靠 alternate signal stack catch(sigaltstack)。

      11. RLIMIT_AS vs RLIMIT_DATA:AS 是整个虚拟地址空间;DATA 仅数据段(init+bss+heap);AS 限制更严格。

      12. RLIMIT_RTPRIO + RLIMIT_RTTIME 防止实时应用滥用——与第 35 章 sched_setscheduler 配合;非特权设实时策略受 RTPRIO 限制。

      13. RLIMIT_RSS Linux 上未实现——存在但无效果;不要用它期望限制 RSS。

      14. RLIMIT_MSGQUEUE/SIGPENDING per-real-UID 累计——同 RLIMIT_NPROC 语义;只影响自己 + descendants。

      15. RLIMIT_SIGPENDING 仅 sigqueue 受限——kill 仍可入队 1 实例/信号/进程(标准信号和实时信号)。

      16. Linux 上 RLIM_SAVED_CUR/MAX 定义为 RLIM_INFINITY——所有限制值可表示;不需要处理「unrepresentable」情况。

      17. shell ulimit 与 getrlimit 单位差异——bash/ksh ulimit 栈大小用 KB;getrlimit/setrlimit 用字节;编程用后者。

      18. fork bomb 防御多层:RLIMIT_NPROC + 系统 threads-max + ulimit -u + cgroup pids.max(容器环境)。

        • 跨章衔接:第 24 章 fork 基础 → 第 35 章 nice/sched_setscheduler → 第 36 章资源限制;第 18 章 mmap → RLIMIT_AS;第 5 章 fcntl F_DUPFD → RLIMIT_NOFILE;第 50 章 mlock → RLIMIT_MEMLOCK;第 47 章 SysV IPC → RLIMIT_MSGQUEUE;第 22 章信号 → RLIMIT_SIGPENDING;第 9 章 set-UID → exec 前 resetrlimit。