Pourquoi n'y a-t-il pas d'identifiants de processus Windows impairs?

160

Il existe de nombreuses manières d’examiner les ID de processus dans Windows.

Par exemple, en utilisant la commande PowerShell:

ps | select Id, ProcessName  | Sort Id | ft -AutoSize

Nous voyons la sortie suivante:

  Id ProcessName         
  -- -----------         
   0 Idle                
   4 System              
 264 svchost             
 388 smss                
 476 csrss               
 536 wininit             
 580 winlogon                      
 620 services            
 628 lsass                          
 728 svchost             
 828 dwm                                     
1060 chrome              
1080 rundll32            
1148 vmms                                        
1620 spoolsv                                                
2912 taskhostex          
3020 explorer       
...     

Tous les identifiants de processus sont des nombres pairs et, en outre, ils sont tous des multiples de 4 .

Il n'y a pas d'ID de processus impairs sur les versions de Windows basées sur Windows NT.

Quelle est la raison pour ça?

Peter Hahndorf
la source
6
Peut-être intéressant: Quelques détails sur linux - justskins.com/forums/why-are-process-ids-204416.html
Dave
13
En effet il n'y en a pas. C'est étrange.
AndreKR

Réponses:

168

"Pourquoi n'y a-t-il pas d'identifiants de processus Windows étranges?"

Le même code qui alloue les descripteurs de noyau est également utilisé pour allouer les ID de processus et de thread. Les identifiants de noyau étant un multiple de quatre, il en va de même pour les identificateurs de processus et de thread.


Pourquoi les ID de processus et de fil sont-ils multiples de quatre?

Sur les systèmes d'exploitation Windows NT, les ID de processus et de threads sont toujours un multiple de quatre. Est-ce juste une coïncidence?

Oui, c'est juste une coïncidence, et vous ne devriez pas compter dessus, car cela ne fait pas partie du contrat de programmation. Par exemple, les identifiants de processus et de threads Windows 95 n'étaient pas toujours des multiples de quatre. (En comparaison, la raison pour laquelle le noyau traite toujours un multiple de quatre fait partie de la spécification et sera garantie dans un avenir proche.)

Les ID de processus et de threads sont des multiples de quatre, conséquence de la réutilisation du code. Le même code qui alloue les descripteurs de noyau est également utilisé pour allouer les ID de processus et de thread. Les identifiants de noyau étant un multiple de quatre, il en va de même pour les identificateurs de processus et de thread. Il s'agit d'un détail d'implémentation, alors n'écrivez pas un code qui en dépend. Je vous dis simplement de satisfaire votre curiosité.

Source Pourquoi les ID de processus et de fil sont-ils multiples de quatre?


Pourquoi les HANDLEs du noyau sont-ils toujours un multiple de quatre?

Ce que l’on ne sait pas très bien, c’est que les deux derniers bits de HANDLE du noyau sont toujours à zéro; en d'autres termes, leur valeur numérique est toujours un multiple de 4. Notez que cela s'applique uniquement aux HANDLE du noyau; il ne s'applique pas aux pseudo-descripteurs ni à aucun autre type de descripteur (descripteurs USER, descripteurs GDI, descripteurs multimédias, etc.). Les descripteurs de noyau sont des éléments que vous pouvez transmettre à la fonction CloseHandle.

La disponibilité des deux derniers bits est enterrée dans le fichier d’en-tête ntdef.h:

//
// Low order two bits of a handle are ignored by the system and available
// for use by application code as tag bits.  The remaining bits are opaque
// and used to store a serial number and table index.
//

#define OBJ_HANDLE_TAGBITS  0x00000003L

Qu'au moins le bit du bas du noyau HANDLEs soit toujours égal à zéro, la fonction GetQueuedCompletionStatus indique que vous pouvez définir le bit du bas de la poignée d'événement pour supprimer la notification de port d'achèvement. Pour que cela fonctionne, le bit du bas doit normalement être zéro.

Ces informations ne sont pas utiles pour la plupart des rédacteurs d'applications, qui devraient continuer à traiter les HANDLE comme des valeurs opaques. Les personnes qui seraient intéressées par les bits de balises sont celles qui implémentent des bibliothèques de classes de bas niveau ou encapsulent des objets du noyau dans un cadre plus large.

Source Pourquoi les HANDLE du noyau sont-ils toujours un multiple de quatre?


Lectures complémentaires


DavidPostill
la source
3
Une citation indique "vous ne devriez pas vous y fier car cela ne fait pas partie du contrat de programmation", mais la revendication suivante ntdef.h indique que les bits sont "disponibles pour être utilisés par le code de l'application en tant que bits de balise". La documentation dans un fichier d'en-tête public est à peu près aussi proche d'un "contrat de programmation" que vous pouvez obtenir, de sorte que la première revendication est incorrecte.
BlueRaja - Danny Pflughoeft
2
@BlueRaja, "Ce que nous savons assez mal, c'est que les deux derniers bits de HANDLE du noyau sont toujours nuls; en d'autres termes, leur valeur numérique est toujours un multiple de 4. " Le code dans ntdef.h s'applique également à d'autres types de descripteurs. (Poignées USER, GDI, multimédia ...)
DavidPostill
37
@BlueRaja: les handles du noyau sont multiples de quatre et c'est contractuel, vous pouvez donc vous y fier; ids de processus (qui ne sont pas les mêmes que les poignées processus), au contraire, arriver à être un multiple de quatre, mais c'est juste un détail de mise en œuvre, de sorte que vous ne devriez pas compter sur elle.
Matteo Italia
6
@BlueRaja Je pense que Raymond vous dirait que celui qui a écrit la documentation a regardé le monde à travers des lunettes colorées et ne fait donc référence qu'aux poignées du noyau et non à d'autres types de poignées.
CodesInChaos
1
@Mehrdad: eh bien, les descripteurs USER et GDI ne sont généralement pas appelés des descripteurs "kernel" (bien qu'ils soient générés par des composants s'exécutant en mode noyau).
Matteo Italia