讲师中心 微信公众号
AI工具推荐 视频效率加速

Linux 中 PID 是如何分配的?

阿涛吖_4467

阿涛吖_4467

发布时间:2026-01-25 19:43:36

|

375人浏览过

|

来源于php中文网

原创

Linux内核用位图找最小空闲PID:从1开始扫描首个为0的比特位,置1后返回编号;位图每页管32768个PID,对应默认pid_max值。

linux 中 pid 是如何分配的?

内核用位图找最小空闲 PID

Linux 分配 PID 的核心动作是:从 1 开始,扫描位图(bitmap)中第一个值为 0 的比特位,将其置 1,并返回对应编号。这个“最小可用号”策略保证了 PID 尽可能紧凑,也便于用户快速识别“刚起的进程”。位图按页组织,每页 4096 字节 → 可管理 32768 个 PID(4096 × 8),正好匹配默认 /proc/sys/kernel/pid_max 值。

常见错误现象:fork() 失败报 Resource temporarily unavailable,不一定是内存不足,很可能是位图里真没空位了——比如 pid_max=32768 时系统已有 32767 个活进程(PID 1 被 systemd 占着),再 fork 就会失败。

  • last_pid 是全局变量,记录上次成功分配的 PID,下次从 last_pid + 1 开始找,避免每次都从头扫
  • 前 RESERVED_PIDS(通常为 300)不参与动态分配,留给内核线程和关键守护进程
  • 位图本身不存进程信息,只管“编号是否被占”,真正关联进程靠 struct pid 和 task_struct 的双向指针

为什么 PID 1 总是 systemd,而 PID 2 不稳定?

PID 1 是硬编码保留的:内核启动后直接调用 kernel_thread() 创建第一个用户态进程,强制指定 PID 为 1,后续所有进程都由它派生。现代发行版几乎都用 systemd 占据该位置;若换成 sysvinit 或 openrc,PID 1 还是它,只是二进制不同。

PID 2 则没有这种保障:它是内核线程 kthreadd 的 PID,但该线程在 rest_init() 中创建,时机紧邻 PID 1,一旦启动顺序微调(如 init 进程初始化稍慢),PID 2 就可能被其他早期内核线程抢走。所以脚本里写死 kill -9 2 是危险操作。

linux-sysadmin
linux-sysadmin

Linux系统管理专家,覆盖12大模块:用户权限、SSH、存储、网络、systemd、防火墙、日志监控、备份恢复、TLS证书、Ansible、容器、IaC。提供配置、验证、加固、监控、备份、自动化、故障排查、回滚闭环。关键词:useradd、sudo、sshd_config、chmod、SEL...

下载
  • 不要依赖 PID 2 指向特定线程,查 ps -o pid,comm -p 2 才能确认当前是什么
  • PID 0 固定属于 swapper(调度器空闲进程),永远不可见、不可 kill
  • 容器内看到的 PID 1 是命名空间局部 PID,其全局 PID 一定是另一个大数,可通过 /proc/1/status 的 NSpid 字段验证

pid_max 调大就能无限开进程?别信

调高 pid_max(比如 sysctl -w kernel.pid_max=4194304)只是放宽了编号池上限,并不等于系统能真的运行 400 万个进程。每个 PID 对应一个 task_struct 结构体,占用约 5–10 KB 内存;PID 池扩大四倍,仅这部分内存就多吃掉上 GB。更现实的瓶颈往往是 ulimit -u(单用户 nproc 限制)或 RLIMIT_AS(地址空间)。

典型误判场景:监控显示 ps -eLf | wc -l 输出 3000,sysctl kernel.pid_max 是 32768,就以为还有 29000 个 PID 可用——其实大量 PID 已被僵尸进程(Z 状态)占着未回收,ps aux | awk '$8 ~ /Z/ {count++} END{print count+0}' 才是真实“卡住”的数量。

  • 调整 pid_max 后必须重启部分服务(如 systemd 的子进程不会自动感知新上限)
  • 容器环境要同时调大宿主机 pid_max 和容器内 pid cgroup 限额,否则 docker run --pids-limit 会优先触发
  • 高频 fork/exit 场景(如短命 CGI 进程)建议用 pid_max=65536 + echo 1 > /proc/sys/kernel/panic_on_oom 避免位图扫描拖慢分配

alloc_pid() 函数里最易忽略的三件事

看内核源码 kernel/pid.c 的 alloc_pid(),表面只是遍历命名空间层级分配数字,但有三个细节常被跳过:

  • 它先分配 struct pid 内存(来自 per-namespace 的 pid_cachep slab),再逐层调用 idr_alloc_cyclic() 填数字——如果某层命名空间的 IDR 树已满,整个分配就失败,不是重试而是直接 return ERR_PTR(-EAGAIN)
  • CLONE_NEWPID 创建新命名空间时,子空间的 level 比父空间 +1,且 numbers[] 数组长度 = level + 1,意味着嵌套 10 层容器后,每个进程要维护 11 个 PID 值(1 个全局 + 10 个局部)
  • 分配成功后,task_struct->pid 赋的是局部 PID(即当前命名空间视角的编号),而信号发送、kill() 系统调用底层用的却是全局 PID——这个转换在 find_vpid() 里完成,不是零成本

真正复杂的从来不是“怎么分”,而是“分完之后怎么让所有子系统(调度、cgroup、ptrace、信号)都认这个号”。PID 管理是 Linux 内核里少有的横跨 namespace、memory、scheduling 三大子系统的胶水逻辑,动它之前,先确认你改的到底是编号池,还是整个进程身份体系。

热门AI工具

更多
Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

Lovart
Lovart Hot

一款面向视觉设计创作的AI设计平台,可通过智能体和画布工作流辅助制作海报、Logo、网页、PPT及其他视觉内容。

墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

Laper
Laper Hot

Laper是专为编剧、导演和制片人推出的 AI 原生剧本创作工具。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

相关专题

更多
python中print函数的用法
python中print函数的用法

python中print函数的语法是“print(value1, value2, ..., sep=' ', end=' ', file=sys.stdout, flush=False)”。本专题为大家提供print相关的文章、下载、课程内容,供大家免费下载体验。

2360

2023.09.27

python print用法与作用
python print用法与作用

本专题整合了python print的用法、作用、函数功能相关内容,阅读专题下面的文章了解更多详细教程。

229

2026.02.03

resource是什么文件
resource是什么文件

Resource文件是一种特殊类型的文件,它通常用于存储应用程序或操作系统中的各种资源信息。它们在应用程序开发中起着关键作用,并在跨平台开发和国际化方面提供支持。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

320

2023.12.20

counta和count的区别
counta和count的区别

Count函数用于计算指定范围内数字的个数,而CountA函数用于计算指定范围内非空单元格的个数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2448

2023.11.20

全局变量怎么定义
全局变量怎么定义

本专题整合了全局变量相关内容,阅读专题下面的文章了解更多详细内容。

3745

2025.09.18

python 全局变量
python 全局变量

本专题整合了python中全局变量定义相关教程,阅读专题下面的文章了解更多详细内容。

1550

2025.09.18

c++ 全局变量
c++ 全局变量

本专题整合了c++全局变量的使用、定义、作用域等等内容,阅读专题下面的文章了解更多详细内容。

199

2026.03.17

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

3994

2025.06.09

Buffalo框架数据库开发全教程
Buffalo框架数据库开发全教程

本专题围绕Buffalo框架数据库开发,讲解database.yml多环境配置、soda与fizz迁移生成回滚、模型结构体标签、增删改查与条件查询、一对多与多对多关联、数据校验、回调钩子、事务处理及原生SQL执行能力。

80

2026.09.23

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Buffalo框架快速入门指南
Buffalo框架快速入门指南

共0课时 | 0人学习

Valgrind支持平台说明
Valgrind支持平台说明

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn