ulimit -i 限制的是单个用户所有进程共用的待处理信号总数,而非单进程独立上限;其值对应rlimit_sigpending,超限时sigqueue()返回eagain。

Linux内核信号处理限制不能通过内核模块或sysctl直接配置,必须从用户空间资源限制(ulimit)和内核编译/启动参数两层入手,核心是控制RLIMIT_SIGPENDING和信号栈大小。
查看当前进程的信号队列限制
每个进程能排队等待处理的信号数量由RLIMIT_SIGPENDING决定,它属于ulimit -i(pending signals)范畴:
-
ulimit -i显示当前shell会话下进程可挂起的信号数上限(即RLIMIT_SIGPENDING软限制) -
ulimit -Hi显示硬限制值 - 该限制按**用户ID**统计,不是单个进程独立计数:所有同UID进程共用这个上限
- 若应用频繁使用
sigqueue()发送带数据的实时信号,ulimit -i过低会导致errno = EAGAIN
临时修改信号队列上限
在启动服务前调整,适用于调试或短期扩容:
在无 root/sudo 权限的环境(云容器、VPS、隔离主机)中安装并配置 OpenClaw 浏览器工具的 headless Chrome。适用场景:...
- 提升软限制(需不超过硬限制):
ulimit -i 2048 - 提升硬限制(需root权限):
sudo ulimit -Hi 4096 - 注意:
ulimit只影响当前shell及其子进程,systemd服务默认不继承父shell限制
systemd服务的持久化配置
对守护进程生效,必须显式声明,否则沿用系统默认值(通常为122880):
- 编辑服务单元文件,如
/etc/systemd/system/myapp.service - 在
[Service]段添加:LimitSIGPENDING=8192 - 重载并重启:
sudo systemctl daemon-reload && sudo systemctl restart myapp - 验证是否生效:
systemctl show myapp.service | grep SIGPENDING或检查进程的/proc/PID/status中SigQ字段
信号处理栈大小(SA_ONSTACK场景)
当使用备用栈处理信号(例如在主线程栈已满时仍需响应SIGSEGV),需确保栈空间足够:
- 查看当前信号栈软限制:
ulimit -s(单位KB,对应RLIMIT_STACK,也影响信号备用栈) - 设置信号专用栈大小需在代码中调用
sigaltstack(),但其最大可用空间受ulimit -s约束 - 若日志出现
signal handler returned, but stack overflow detected,说明备用栈溢出,应增大ulimit -s并检查sigaltstack.ss_size是否合理
真正容易被忽略的是:信号队列限制(RLIMIT_SIGPENDING)是**按用户汇总统计**的,不是单进程隔离;而sigqueue()失败时返回EAGAIN而非ENOMEM,排查时容易误判为内存不足。










