Linux PID是如何生成的?
1. 概述
你有没有想过当我们启动或终止一个进程时,幕后发生了什么?在本教程中,我们将学习 Linux 如何为进程生成 PID。
2.Linux的进程表
**Linux 内核使用一种称为进程表的数据结构来处理进程调度等各种任务。**每当我们启动一个进程时,它都会在表中插入一个包含以下信息的条目:
- PID
- 父进程
- 环境变量
- 经过时间
- 状态 – D(不间断)、R(运行)、S(睡眠)、T(停止)或Z(僵尸)之一
- 内存使用情况
我们可以通过安装在/proc目录下的procfs*文件系统,通过各种资源监控工具(如top )来使用这些信息。*
让我们通过运行top命令来查看一些信息:
Mem: 4241112K used, 12106916K free, 360040K shrd, 20K buff, 1772160K cached
CPU: 0.8% usr 0.8% sys 0.0% nic 98.3% idle 0.0% io 0.0% irq 0.0% sirq
Load average: 0.26 0.33 0.35 1/489 21888
PID PPID USER STAT VSZ %VSZ CPU %CPU COMMAND
1 0 root S 2552 0.0 10 0.0 init
30405 30404 blogdemo S 2552 0.0 7 0.0 /bin/sh
219 1 root S 2552 0.0 10 0.0 /bin/getty 38400 tty2
1309 1308 blogdemo S 2552 0.0 9 0.0 /bin/sh
21873 640 blogdemo S 2552 0.0 5 0.0 [sleep]
21874 21758 blogdemo R 2552 0.0 8 0.0 top
3. PID 生成
Linux 按顺序分配进程 ID,从 0 开始并保持在最大限制以下。
内核的空闲 任务进程,它确保一个可运行的任务始终可用于调度,保留 PID 0,而作为第一个进程的 init 系统保留 PID 1。
我们可以通过查看*/proc/sys/kernel/pid_max*文件来检查系统的限制。它通常是一个 5 位数字:
$ cat /proc/sys/kernel/pid_max
32768
我们可以通过将所需数字以 root 身份写入文件来将限制配置为最大数量2 22 (4,194,304):
# desired=4194304
# echo $desired > /proc/sys/kernel/pid_max
# desired=9999999
# echo $desired > /proc/sys/kernel/pid_max
sh: write error: Invalid argument
我们的第二次尝试失败,因为数字大于2 22。
当我们启动一个进程时,会生成一个进程的 PID 以允许唯一地识别它。这只需将当前最高 PID 加 1 即可。
让我们借助一个简单的 shell 脚本来确认这一点:
#!/bin/sh -e
# This script assumes that printf is a shell builtin and hence doesn't take up extra PIDs.
highest=0
for pid in /proc/[0-9]*; do
pid="${pid##*/}" # Extract PID
[ "$pid" -gt "$highest" ] && highest="$pid" # -gt means "greater than"
done
printf "Highest PID is %d\n" "$highest"
for _ in $(seq 4); do
printf "Launched new process with PID %d\n" "$(readlink /proc/self)"
done
首先,我们计算了系统上的最高 PID。接下来,我们启动了四个readlink进程,每个进程都会检查分配给它们的新 PID。
让我们看看脚本的输出:
Highest PID is 10522
Launched new process with PID 10524
Launched new process with PID 10525
Launched new process with PID 10526
Launched new process with PID 10527
我们可以注意到,在我们检查最高 PID 和打印新 PID 之间存在 1 个 PID 的差距,因为seq命令本身会启动一个额外的进程。因此,外部进程通过创建新的 PID 来影响此类测试。
4. 我们能用完 PID 吗?
我们在上一节中讨论了最大 PID 限制,那么当我们达到该限制时会发生什么?
如果我们达到最大 PID 限制,则以下 PID 将环绕最大值。这是因为内核从 1 开始并寻找属于现在已经完成的进程的空闲 PID。
我们应该注意,只有当父进程收集到其终止状态时,才认为进程“已完成” 。因此,恶意编码的程序可能会使我们的 PID 系统挨饿。