Подтвердить что ты не робот

Как Linux определяет следующий PID?

Как Linux определяет следующий PID, который он будет использовать для процесса? Цель этого вопроса - лучше понять ядро ​​Linux. Не бойтесь опубликовать исходный код ядра. Если PID распределяются последовательно, как Linux заполняет пробелы? Что происходит, когда оно заканчивается?

Например, если я запускаю PHP script из Apache, который выполняет <?php print(getmypid());?>, то тот же PID будет распечатан в течение нескольких минут при обновлении. Этот период времени является функцией количества запросов, которые получает apache. Даже если есть только один клиент, PID в конечном итоге изменится.

Когда PID изменится, это будет близкое число, но как близко? Число не выглядит полностью последовательным. Если я выполняю ps aux | grep apache, я получаю много процессов:

enter image description here

Как Linux выбирает следующий номер? Предыдущие несколько PID все еще запущены, а также самый последний PID, который был напечатан. Как apache выбирает повторное использование этих PID?

4b9b3361

Ответ 1

Ядро выделяет PID в диапазоне (RESERVED_PIDS, PID_MAX_DEFAULT). Он делает это последовательно в каждом пространстве имен (задачи в разных пространствах имен могут иметь одинаковые идентификаторы). Если диапазон исчерпан, назначение pid обтекает.

Некоторые соответствующие коды:

Внутри 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 идентификаторы; соответствующую структуру можно найти в /include/linux/pid.h. Помимо идентификатора, он содержит список задач с этим идентификатором, счетчиком ссылок и хешированным списком node для быстрого доступа.

Причина, по которой PID не появляются последовательно в пространстве пользователя, заключается в том, что планирование ядра может разветвлять процесс между вызовами fork() процесса. На самом деле это очень распространено.

Ответ 2

Я предпочел бы поведение, которое вы наблюдаете из другого источника:

Хорошие веб-серверы обычно имеют несколько экземпляров процессов, чтобы сбалансировать нагрузку на запросы. Эти процессы управляются в пуле и присваиваются определенному запросу каждый раз, когда приходит запрос. Для оптимизации производительности Apache, вероятно, назначает один и тот же процесс кучу последовательных запросов от одного и того же клиента. После определенного количества запросов этот процесс завершается и создается новый.

Я не считаю, что более чем одному процессу в последовательности присваивается один и тот же PID linux.

Как вы говорите, новый PID будет близок к последнему, я полагаю, что Linux просто назначает каждому процессу последний PID + 1. Но есть процессы, возникающие и постоянно заканчивающиеся приложениями и системой программ, поэтому вы не можете предсказать точное число запущенного процесса apache.

Кроме того, вы должны не использовать любое предположение о назначении PID в качестве основы для того, что вы реализуете. (См. Также комментарий sanmai.)

Ответ 3

PIDs являются последовательными в большинстве систем. Вы можете видеть, что, начав несколько процессов самостоятельно на незанятой машине.

например. повторите вызов истории со стрелкой вверх, чтобы повторно запустить команду, которая печатает свой собственный 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

Не зависеть от этого: по соображениям безопасности некоторые люди запускают ядра, которые проводят дополнительное время процессора, чтобы случайным образом выбирать новые PID.