Ядро выделяет PID в диапазоне (RESERVED_PIDS, PID_MAX_DEFAULT).Это происходит последовательно в каждом пространстве имен (задачи в разных пространствах имен могут иметь одинаковые идентификаторы).Если диапазон исчерпан, назначение 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
идентификатор;соответствующая структура может быть найдена в /include/linux/pid.h
.Помимо идентификатора, он содержит список задач с этим идентификатором, счетчик ссылок и узел хешированного списка для быстрого доступа.
Причина, по которой идентификаторы PID не отображаются последовательно в пространстве пользователя, заключается в том, что планирование ядра может привести к потере процессамежду вашим процессом 'fork()
звонками.На самом деле это очень распространено.