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?
Le même code qui alloue les descripteurs de noyau est également utilisé pour allouer les ID de processus et de thread. Étant donné que les poignées du noyau sont un multiple de quatre, donc aussi les identifiants des processus et du fil.
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, le processus Windows 95 et les ID de fil ne sont 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.)
Processus et ID fil sont des multiples de quatre comme un effet secondaire 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. Étant donné que les poignées du noyau sont un multiple de quatre, donc aussi les identifiants des processus et du fil. Ceci est un détail de mise en œuvre, donc ne pas écrire du code qui repose sur elle. Je vous dis simplement de satisfaire votre curiosité.
Source Pourquoi les ID de processus et de fil sont-ils multiples 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, GDI, descripteurs multimédia ...). 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 balise 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 toujours du noyau gère un multiple de quatre?