ulimit -u 是用户级进程/线程总数限制,非系统最大线程数;真正决定系统线程上限的是 kernel.threads-max 和 kernel.pid_max,且实际可用线程数 ≈ min(threads-max, pid_max),二者需同步配置,否则单改无效。

ulimit -u 显示的是用户级线程数限制,不是系统最大线程数
很多人看到 ulimit -u 输出 4096 就以为这是“系统最大线程数”,其实它只控制单个用户能创建的进程+线程总数(即 nproc),和内核实际能调度的线程上限无关。真正决定系统能跑多少线程的是 kernel.threads-max 和 kernel.pid_max 这两个内核参数。
/proc/sys/kernel/threads-max 和 pid_max 的区别与取值逻辑
kernel.threads-max 是内核理论上能创建的线程总数上限,但它受 kernel.pid_max 制约——因为每个线程在 Linux 中都对应一个 PID,而 PID 编号空间由 pid_max 定义。所以实际可用线程数 ≈ min(threads-max, pid_max)。
-
cat /proc/sys/kernel/threads-max通常默认是max(2048, pid_max / 2) -
cat /proc/sys/kernel/pid_max默认为 32768(CentOS 7),但可调至 4194304 - 若你设
threads-max = 1000000,但pid_max = 32768,那线程数仍卡在 32768 左右
永久修改 threads-max 和 pid_max 的正确写法
编辑 /etc/sysctl.conf,必须同时设置两项,否则单改一个无效:
CentOS Linux 7.9.2009是传统CentOS Linux 7的最后主要版本,也是很多企业历史服务器中仍可能遇到的系统版本。它以稳定、兼容RHEL 7生态、文档丰富和软件支持广泛著称,曾长期用于Web服务、数据库、虚拟化节点和企业内部业务系统。不过CentOS Linux 7已于2024年6月30日停止维护,现在继续使用会面临安全补丁缺失风险。该版本更适合旧业务迁移、历史环境恢复或离
kernel.pid_max = 1048576 kernel.threads-max = 1048576
然后执行 sysctl -p 生效。注意:threads-max 值不能超过 pid_max,否则内核会自动向下取整到 pid_max。
- 不要用
kernel.max_threads—— 该参数不存在,是常见笔误 - 不要只改
threads-max而忽略pid_max,否则重启后仍被截断 - 修改后验证:运行
cat /proc/sys/kernel/pid_max和cat /proc/sys/kernel/threads-max确认数值一致且生效
为什么改了 sysctl 还是起不来大量线程?检查 pam_limits 是否加载
即使内核允许百万线程,普通用户仍受 /etc/security/limits.d/*.conf 限制。CentOS 7 默认启用 pam_limits.so,但如果你用 systemd 启动服务(比如 Elasticsearch、Java 应用),它可能绕过 limits.conf。
- 对交互式登录用户:确认
/etc/security/limits.d/20-nproc.conf中有类似* soft nproc 65535和* hard nproc 65535 - 对 systemd 服务:必须在 service 文件里显式设置
LimitNPROC=65535,否则无视 limits.conf - 验证方式:启动目标进程后,查其
/proc/PID/limits中Max processes行是否匹配预期
最常被忽略的一点:threads-max 和 pid_max 是全局硬边界,但单个进程能否达到这个数,还取决于内存——每个线程默认栈 8MB,10 万线程就要 800GB 内存。没配 ulimit -s 或 JVM -Xss,光调内核参数也没用。










