Как создаются PID?

42

В * nix PID являются уникальными идентификаторами для запуска процессов. Как создаются PID? Это просто целое число, которое увеличивается, или более сложная структура, такая как список? Как они перерабатываются? Под рециркуляцией я подразумеваю, что, когда процесс завершается, его PID будет в конечном итоге использоваться другим процессом.

Джованни Фуншал
источник

Ответы:

39

Как гласит Википедия ,

В Unix идентификаторы процессов обычно распределяются последовательно, начиная с 0 и увеличиваясь до максимального значения, которое варьируется от системы к системе. Как только этот предел достигнут, распределение возобновляется с нуля и снова увеличивается. Однако для этого и последующих проходов все идентификаторы PID, все еще назначенные процессам, пропускаются.

так что это действительно очень простая политика для «генерации», просто увеличивая счетчик и «перерабатывая», просто оборачивайте число вокруг максимального значения и продолжайте увеличивать до тех пор, пока не найдете номер, который был присвоен процессу, который завершился и имеет были удалены из таблицы процессов.

Некоторые реализации Unix, такие как AIX, используют менее простую политику, см., Например, этот FAQ .

Алекс Мартелли
источник
Спасибо за ответ. Кстати, что именно это политика AIX "это менее просто"?
1
@ Helltone, я не думаю, что AIX документирует, какую именно политику он использует (поэтому она может измениться при любом выпуске), но вы можете думать об этом как о генерации случайных чисел в соответствующем диапазоне (который повторяется до тех пор, пока не будет сгенерирован PID, то есть в настоящее время не используется).
Алекс Мартелли
Этот алгоритм кажется мне немного проблематичным. Как вы гарантируете, что не попадете в тупик? И нет ли проблемы с производительностью?
1
Ядро находится под контролем и не должно ничего блокировать, так как же оно может зайти в тупик? Да, нужно заплатить небольшую цену за производительность (небольшая дополнительная нагрузка во время разветвления - скажем, пара десятков машинных инструкций для конгруэнтного чтения PRNG или / dev / urandom, по сравнению с гораздо меньшим для встречного приращения), но это всегда случай мер, направленных на повышение безопасности (например, проверьте загрузку ЦП HTTPS-связи против простого HTTP ;-).
Алекс Мартелли
Я имел в виду livelock ( while(true);), извините, я быстро отвечал ;-)
11

Различается.

Большинство систем просто хранят счетчик последнего сгенерированного PID, добавляют его (упаковка с максимальным числом, например, 65535 или немного меньше - часто это происходит при 65000 или даже 60000), и проверяют, что число не используется в настоящее время ( повторяется, если PID все еще используется - таким образом, PID 1, ядро, все еще там и не переиздается).

Другие системы, ориентированные на безопасность, генерируют случайное число и проверяют, что оно не используется.

В любой момент времени гарантируется, что все номера PID являются уникальными.

Джонатан Леффлер
источник
9

Что касается утилизации, вопрос, о которой следует помнить, состоит в том, что pid не становится доступным, как только процесс с этим pid завершается. Pid не становится доступным, пока родительский элемент этого процесса не соберет статус завершения своего дочернего элемента с помощью какой-либо формы системного вызова wait (). Ребенок, которого уволили, но чей родитель не произвел ожидание, называется зомби и обычно будет отображаться в пс как несуществующий. Плохо ведущий родитель может заморозить систему pids, если он запускает дочерние элементы и не ждет их ().

Если родитель процесса умирает до того, как он соберет статус ребенка, это нормально. Дочерний объект наследуется init, который будет следить за выдачей wait () и повторным использованием pid.

frankc
источник
Это очень важная деталь. Без этого даже простой myprog &последовал wait $!бы UB.
Андреас
3

Они являются порядковыми номерами и имеют циклический переход (по значению, зависящему от ОС), если система работает достаточно долго. Числа никогда не используются повторно, если они не являются свободными в точке fork().

Donal Fellows
источник