¿Cómo se generan los PID?

42

En * nix, los PID son identificadores únicos para ejecutar procesos. ¿Cómo se generan los PID? ¿Es solo un número entero que se incrementa o una estructura más compleja como una lista? ¿Cómo se reciclan? Al reciclar quiero decir que, cuando un proceso termina, su PID eventualmente será reutilizado por otro proceso.

Giovanni Funchal
fuente

Respuestas:

39

Como dice Wikipedia ,

En Unix, las ID de proceso generalmente se asignan de forma secuencial, comenzando en 0 y aumentando hasta un valor máximo que varía de un sistema a otro. Una vez que se alcanza este límite, la asignación se reinicia en cero y nuevamente aumenta. Sin embargo, para este y los pases posteriores, se omiten los PID que aún se asignan a los procesos.

así que es realmente una política muy simple para "generación", simplemente incremente un contador y "reciclaje", simplemente ajuste el número a un valor máximo y siga incrementándolo hasta que encuentre un número que se asignó a un proceso que ha finalizado y tiene sido eliminado de la tabla de procesos.

Algunas implementaciones de Unix, como AIX, usan una política que es menos simple; consulte, por ejemplo, estas preguntas frecuentes .

Alex Martelli
fuente
Gracias por la respuesta. Por cierto, ¿qué es exactamente esta política de AIX "que es menos simple"?
1
@Helltone, no creo que AIX documente exactamente qué política utiliza (por lo que podría cambiar en cualquier versión), pero podría pensar en ella como una generación de números aleatorios en el rango apropiado (que se repite hasta que se genera un PID que es actualmente no en uso).
Alex Martelli
Este algoritmo me parece un poco problemático. ¿Cómo se asegura de no encontrarse con un punto muerto? ¿Y no hay un problema de rendimiento?
1
El kernel tiene el control y no necesita bloquear nada, entonces, ¿cómo podría llegar a un punto muerto? Sí, hay un pequeño precio de rendimiento a pagar (una pequeña sobrecarga adicional en el momento de la bifurcación; digamos un par de docenas de instrucciones de la máquina para una lectura congruente de PRNG o / dev / urandom, frente a muchas menos para un contra-incremento), pero eso siempre es el caso de medidas destinadas a mejorar la seguridad (verifique la sobrecarga de la CPU de la comunicación HTTPS frente a HTTP simple, por ejemplo ;-).
Alex Martelli
Me refería a livelock ( while(true);), lo siento, estaba respondiendo rápidamente ;-)
11

Varía.

La mayoría de los sistemas simplemente mantienen un recuento del último PID generado, agregan uno (ajuste en un número máximo como 65535 o un poco más pequeño, a menudo el ajuste ocurre en 65000 o incluso 60000), y verifique que el número no esté actualmente en uso ( repetir si el PID todavía está en uso, por lo que el PID 1, el núcleo, todavía está allí y no se 'vuelve a emitir').

Otros sistemas con mentalidad de seguridad generan un número al azar y verifican que no esté en uso.

En cualquier momento, se garantiza que todos los números PID son únicos.

Jonathan Leffler
fuente
9

En cuanto a la parte de reciclaje de la pregunta, una cosa a tener en cuenta es que un pid no estará disponible tan pronto como finalice el proceso con ese pid. El pid no estará disponible hasta que el padre de ese proceso recopile el estado de terminación de su hijo a través de alguna forma de la llamada al sistema wait (). Un niño que se termina pero cuyo padre no ha emitido una espera se llama zombie y, por lo general, aparece en un ps como difunto. Es posible que un padre con mal comportamiento muera de hambre el sistema de pids si lanza niños y no los espera ().

Si el padre de un proceso muere antes de que recopile el estado de un hijo, está bien. El hijo hereda al niño, que se asegurará de que se emita un wait () y se recicle el pid.

frankc
fuente
Este es un detalle muy importante. Sin él, incluso un simple myprog &seguido wait $!sería UB.
Andreas
3

Son números de secuencia y se envuelven (en un valor específico del sistema operativo) si el sistema está funcionando durante el tiempo suficiente. Los números nunca se reutilizan a menos que sean libres en el momento fork().

Compañeros de Donal
fuente