Perché non ci sono ID processo di Windows dispari?


160

Esistono molti modi per esaminare gli ID di processo in Windows.

Ad esempio, usando il comando PowerShell:

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

Vediamo il seguente output:

  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       
...     

Tutti gli ID di processo sono numeri pari e, inoltre, sono tutti multipli di 4 .

Non ci sono ID di processo dispari su qualsiasi versione di Windows basata su Windows NT.

Qual è la ragione di ciò?


6
Forse interessante: alcuni dettagli su Linux - justskins.com/forums/why-are-process-ids-204416.html
Dave,

13
In effetti non ce ne sono. È strano.
AndreKR,

Risposte:


168

"Perché non ci sono ID di processo di Windows dispari?"

Lo stesso codice che alloca gli handle del kernel viene utilizzato anche per allocare gli ID di processo e thread. Poiché gli handle del kernel sono un multiplo di quattro, lo sono anche gli ID di processo e thread.


Perché gli ID di processo e thread sono multipli di quattro?

Sui sistemi operativi basati su Windows NT, gli ID di processo e thread sono sempre multipli di quattro. È solo una coincidenza?

Sì, è solo una coincidenza e non dovresti fare affidamento su di esso poiché non fa parte del contratto di programmazione. Ad esempio, gli ID processo e thread di Windows 95 non erano sempre multipli di quattro. (In confronto, la ragione per cui gli handle del kernel sono sempre multipli di quattro fa parte delle specifiche e sarà garantita per il prossimo futuro.)

Gli ID di processo e thread sono multipli di quattro come effetto collaterale del riutilizzo del codice. Lo stesso codice che alloca gli handle del kernel viene utilizzato anche per allocare gli ID di processo e thread. Poiché gli handle del kernel sono un multiplo di quattro, lo sono anche gli ID di processo e thread. Questo è un dettaglio dell'implementazione, quindi non scrivere codice che si basa su di esso. Ti sto solo dicendo di soddisfare la tua curiosità.

Origine Perché gli ID di processo e thread sono multipli di quattro?


Perché le MANIGLIE del kernel sono sempre un multiplo di quattro?

Non molto noto è che i due bit inferiori di HANDLE del kernel sono sempre zero; in altre parole, il loro valore numerico è sempre un multiplo di 4. Nota che questo vale solo per le MANIGLIE del kernel; non si applica agli pseudo-handle o ad altri tipi di handle (handle USER, handle GDI, handle multimediali ...) Gli handle del kernel sono elementi che è possibile passare alla funzione CloseHandle.

La disponibilità dei due bit inferiori è sepolta nel file di intestazione 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

Il fatto che almeno il bit inferiore di HANDLE del kernel sia sempre zero è implicito nella funzione GetQueuedCompletionStatus, che indica che è possibile impostare il bit inferiore dell'handle dell'evento per sopprimere la notifica della porta di completamento. Affinché ciò funzioni, il bit inferiore deve essere normalmente pari a zero.

Questa informazione non è utile per la maggior parte dei writer di applicazioni, che dovrebbero continuare a trattare le MANIGLIE come valori opachi. Le persone che sarebbero interessate ai bit di tag sono quelle che stanno implementando librerie di classi di basso livello o stanno avvolgendo oggetti kernel all'interno di un framework più ampio.

Fonte Perché le MANIGLIE del kernel sono sempre un multiplo di quattro?


Ulteriori letture



3
Una citazione dice "non dovresti fare affidamento su di esso poiché non fa parte del contratto di programmazione", ma poi le successive affermazioni ntdef.h dicono che i bit sono "disponibili per l'uso dal codice dell'applicazione come bit di tag". La documentazione in un file di intestazione pubblica si avvicina il più possibile a un "contratto di programmazione" , quindi il primo reclamo non è corretto.
BlueRaja - Danny Pflughoeft il

2
@BlueRaja, "Non molto noto è che i due bit inferiori degli HANDLE del kernel sono sempre zero; in altre parole, il loro valore numerico è sempre un multiplo di 4. " Il codice in ntdef.h si applica anche ad altri tipi di handle (Maniglie USER, maniglie GDI, maniglie multimediali ...)
DavidPostill

37
@BlueRaja: gli handle del kernel sono multipli di quattro ed è contrattuale, quindi puoi fare affidamento su di esso; ID di processo (che sono , non lo stesso che gestisce processo), invece, capita di essere multiplo di quattro, ma questo è solo un dettaglio di implementazione, quindi non si dovrebbe fare affidamento su di esso.
Matteo Italia,

6
@BlueRaja Penso che Raymond ti direbbe che chiunque abbia scritto la documentazione ha guardato il mondo attraverso occhiali color kernel e quindi si è riferito solo agli handle del kernel e non ad altri tipi di handle.
CodesInChaos,

1
@Mehrdad: beh, gli handle USER e GDI non sono normalmente chiamati handle "kernel" (sebbene siano generati da componenti in esecuzione nella cosiddetta modalità kernel).
Matteo Italia,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.