2010-08-10 15 views
34

Comment Linux détermine-t-il le prochain PID qu'il utilisera pour un processus? Le but de cette question est de mieux comprendre le noyau Linux. N'ayez pas peur de publier le code source du noyau. Si les PID sont alloués séquentiellement, comment Linux comble-t-il les lacunes? Que se passe-t-il quand il arrive à la fin? Par exemple, si j'exécute un script PHP d'Apache qui exécute un <?php print(getmypid());?>, le même PID sera imprimé pendant quelques minutes lors de l'actualisation. Cette période est fonction du nombre de requêtes reçues par Apache. Même s'il n'y a qu'un seul client, le PID finira par changer.Comment Linux détermine-t-il le prochain PID?

Lorsque le PID change, ce sera un nombre proche, mais à quelle distance? Le nombre ne semble pas entièrement séquentiel. Si je fais un ps aux | grep apache je reçois un bon nombre de processus:

enter image description here

Comment Linux choisir ce numéro suivant? Les quelques PID précédents sont toujours en cours d'exécution, ainsi que le PID le plus récent qui a été imprimé. Comment apache choisit-il de réutiliser ces PID?

Répondre

48

Le noyau alloue des PID dans la plage de (RESERVED_PIDS, PID_MAX_DEFAULT). Il le fait de manière séquentielle dans chaque espace de noms (les tâches dans différents espaces de noms peuvent avoir les mêmes ID). Dans le cas où la plage est épuisée, l'affectation de pid s'enroule autour.

Certains code correspondant:

intérieur 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; 
} 

Notez que la PIDs dans le contexte du noyau sont plus que int identifiants; la structure pertinente peut être trouvée dans /include/linux/pid.h. Outre l'identifiant, il contient une liste de tâches avec cet identifiant, un compteur de référence et un noeud de liste hachée pour un accès rapide.

La raison pour laquelle les PID n'apparaissent pas de manière séquentielle dans l'espace utilisateur est que la planification du noyau peut entraîner un processus entre les appels fork() de votre processus. C'est très commun, en fait.

+0

+ 1 vous êtes un mauvais cul, donc je vous ai donné quelque chose d'autre ... – rook

+0

Y at-il moyen de mapper le PID global et l'espace de noms? –

11

Je préférerais prendre le comportement que vous regardez provient d'une autre source:

Les bons serveurs Web ont généralement plusieurs instances de processus pour équilibrer la charge des demandes. Ces processus sont gérés dans un pool et affectés à une demande spécifique à chaque fois qu'une requête arrive. Pour optimiser les performances, Apache assigne probablement le même processus à un tas de demandes séquentielles provenant du même client. Après un certain nombre de demandes, ce processus est terminé et un nouveau est créé.

Je ne crois pas que plus d'un processus en séquence se voit attribuer le même PID par Linux. Comme vous dites que le nouveau PID va être proche du dernier, je suppose que Linux affecte simplement chaque processus au dernier PID + 1. Mais il y a des processus surgissant et se terminant tout le temps en arrière-plan par les applications et programmes système, vous ne pouvez donc pas prédire le nombre exact de processus apache démarrés ensuite. En dehors de cela, vous devez et non utiliser n'importe quelle hypothèse à propos de l'attribution de PID comme base pour quelque chose que vous implémentez. (Voir aussi le commentaire de sanmai.)

+0

Je pense que c'est partiellement correct, malheureusement, vous n'avez aucune preuve à l'appui de cette réponse. – rook

+0

Maintenant, j'ai, voir les autres réponses. :-) – chiccodoro

+0

btw j'ai été le (+1) – rook

9

PID are sequential sur la plupart des systèmes. Vous pouvez le constater en démarrant plusieurs processus par vous-même sur une machine inactive.

par exemple. utiliser jusqu'à flèche de rappel de l'histoire à exécuter de façon répétitive une commande qui imprime son propre 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 

Ne comptez pas sur ce point: pour des raisons de sécurité, certaines personnes courent des grains qui passent du temps CPU supplémentaire pour choisir au hasard de nouveaux PIDs.

+0

Cela ne semble pas être vrai. – rook

+0

@The Rock: Pourquoi? – chiccodoro

+0

Capture d'écran de @chiccodoro. – rook

3

Les PID peuvent être alloués de manière aléatoire. Il y a a number of ways pour accomplir cela.

+0

Autant que je sache, la randomisation PID a été rejetée par l'équipe de développement du noyau Linux en raison de la sécurité à travers l'obscurité. – Akshay