代码之家  ›  专栏  ›  技术社区  ›  rook

Linux如何确定下一个PID?

  •  36
  • rook  · 技术社区  · 14 年前

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

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

    当pid改变时,它将是一个接近的数字,但有多接近?这个数字似乎不是完全按顺序排列的。如果我执行 ps aux_grep apache i get a fair number of processes:。

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

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

    当pid改变时,它将是一个接近的数字,但有多接近?这个数字似乎不是完全按顺序排列的。如果我做了 ps aux | grep apache 我得到了相当多的过程:

    enter image description here

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

    4 回复  |  直到 9 年前
        1
  •  48
  •   Michael F    14 年前

    内核在范围内分配pid(保留的pids,pid_max_默认值)。它在每个命名空间中按顺序执行(不同命名空间中的任务可以具有相同的ID)。如果范围已用完,PID分配将环绕。

    一些相关代码:

    内部分配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;
    }
    

    ApLoopPIDMAP()

    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 标识符;相关结构可在 /include/linux/pid.h . 除了ID,它还包含一个具有该ID的任务列表、一个引用计数器和一个用于快速访问的哈希列表节点。

    PIDS在用户空间中没有出现顺序的原因是,内核调度可能会在进程之间分叉进程。 fork() 电话。事实上,这很常见。

        2
  •  11
  •   chiccodoro    14 年前

    我宁愿假设你看到的行为 源于另一个来源 :

    好的Web服务器通常有几个流程实例来平衡请求的负载。这些进程在池中进行管理,并在每次请求进入时分配给特定的请求。为了优化性能,Apache可能会为来自同一个客户机的一系列连续请求分配相同的进程。在一定数量的请求之后,该进程将终止并创建一个新的请求。

    我不相信Linux会为多个进程分配相同的PID。

    正如您所说,新的PID将接近最后一个PID,我猜Linux只是为每个进程分配最后一个PID+1。但是有一些进程一直在后台被应用程序和系统程序弹出并终止,因此您无法预测下一步启动的Apache进程的确切数量。

    除此之外,你应该 使用关于pid分配的任何假设作为实现某些内容的基础。(另见Sanmai的评论。)

        3
  •  8
  •   Community CDub    8 年前

    PID are sequential 在大多数系统上。您可以通过自己在空闲机器上启动几个进程来看到这一点。

    例如,使用向上箭头历史记录调用来重复运行一个命令,该命令将打印自己的PID:

    $ ls -l /proc/self
    lrwxrwxrwx 1 root root 0 Mar 15 19:32 /proc/self -> 21491
    $ ls -l /proc/self
    lrwxrwxrwx 1 root root 0 Mar 15 19:32 /proc/self -> 21492
    $ ls -l /proc/self
    lrwxrwxrwx 1 root root 0 Mar 15 19:32 /proc/self -> 21493
    $ ls -l /proc/self
    lrwxrwxrwx 1 root root 0 Mar 15 19:32 /proc/self -> 21494
    

    不要依赖于这一点:出于安全原因,有些人运行那些花费额外CPU时间随机选择新PID的内核。

        4
  •  4
  •   sanmai    14 年前

    PID可以随机分配。有 a number of ways 为了实现这一点。