Linux如何确定它将用于进程的下一个PID?这个问题的目的是更好地理解Linux内核.不要害怕发布内核源代码.如果按顺序分配PID,Linux如何填补这些空白?当它到达终点时会发生什么?

例如,如果我从Apache运行一个PHP脚本,执行<?php print(getmypid());?>次刷新,那么在点击刷新时,相同的PID将打印几分钟.这段时间是apache接收到多少请求的函数.即使只有一个客户机,PID最终也会改变.

当PID改变时,它将是一个接近的数字,但有多接近?这个数字似乎并不完全是连续的.如果我做ps aux | grep apache次,我会得到相当多的过程:

在此处输入图像描述

Linux如何 Select 下一个数字?前几个PID仍在运行,以及最近打印的PID.apache如何 Select 重用这些PID?

推荐答案

内核在以下范围内分配PID(保留的PID,PID最大值默认值).它在每个名称空间中按顺序执行(不同名称空间中的任务可以具有相同的ID).如果量程耗尽,pid分配将结束.

一些相关代码:

Inside alloc_pid(...)

for (i = ns->level; i >= 0; i--) {
    nr = alloc_pidmap(tmp);
    if (nr < 0)
        goto out_free;
    pid->numbers[i].nr = nr;
    pid->numbers[i].ns = tmp;
    tmp = tmp->parent;
}

alloc_pidmap()

static int alloc_pidmap(struct pid_namespace *pid_ns)
{
        int i, offset, max_scan, pid, last = pid_ns->last_pid;
        struct pidmap *map;

        pid = last + 1;
        if (pid >= pid_max)
                pid = RESERVED_PIDS;
        /* and later on... */
        pid_ns->last_pid = pid;
        return pid;
}

请注意,内核上下文中的PID不仅仅是int个标识符;相关 struct 见/include/linux/pid.h.除了id之外,它还包含一个具有该id的任务列表、一个引用计数器和一个用于快速访问的哈希列表 node .

PIDs在用户空间中不按顺序出现的原因是,内核调度可能会在进程的fork()次调用之间Forking 一个进程.事实上,这很常见.

Linux相关问答推荐

C++17/Linux:信号未解锁单独线程中被阻止的网络套接字调用

并行函数的最后一个实例的状态

Shell 脚本程序 - 从日志(log)文件中过滤磁盘空间利用率超过 80% 的行

Linux 的 __fastfail 替代方案?

boost-iostreams 1.59 sparc-solaris 交叉编译失败

如何使 awk 输出更具可读性?

我想使用排序命令对第 5 列进行日期排序.但问题是格式不一致,有什么方法可以做到吗?

ENQCMD 指令的好处和微操作是什么?

进程Forking 后 pthread_key_create() 生成的密钥会发生什么?

判断指定名称的画面是否存在

使用 AWS CLI 进行 Bash - 无法找到凭证

我需要 -D_REENTRANT 和 -pthreads 吗?

哪个程序在给定任何文件的情况下创建一个 C 数组?

yum 可以告诉我哪些存储库提供了特定的包吗?

将参数传递给 awk 脚本文件

如何告诉 CMake 将构建文件放在哪里?

使用单个命令打开 .tar.gz 文件

在 Linux 中,名称与正则表达式匹配的文件的磁盘使用情况?

在 reverse-i-search (Ctrl+R ) , 历史上类似命令之间切换的任何方法

如何在redhat linux上安装maven