Dlaczego nie ma nieparzystych identyfikatorów procesów systemu Windows?

160

Istnieje wiele sposobów sprawdzania identyfikatorów procesów w systemie Windows.

Na przykład za pomocą polecenia PowerShell:

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

Widzimy następujące dane wyjściowe:

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

Wszystkie identyfikatory procesów są liczbami parzystymi, a ponadto są wielokrotnościami 4 .

Nie ma nieparzystych identyfikatorów procesów w żadnej wersji systemu Windows opartej na systemie Windows NT.

Jaki jest tego powód?

Peter Hahndorf
źródło
6
Być może interesujące: niektóre szczegóły na temat Linuksa - justskins.com/forums/why-are-process-ids-204416.html
Dave
13
Rzeczywiście nie ma żadnych. To dziwne.
AndreKR,

Odpowiedzi:

168

„Dlaczego nie ma nieparzystych identyfikatorów procesów systemu Windows?”

Ten sam kod, który przydziela uchwyty jądra, służy również do przydzielania identyfikatorów procesów i wątków. Ponieważ uchwyty jądra są wielokrotnością czterech, również identyfikatory procesów i wątków.


Dlaczego identyfikatory procesów i wątków są wielokrotnościami czterech?

W systemach operacyjnych opartych na Windows NT identyfikatory procesów i wątków są zawsze wielokrotnością czterech. Czy to tylko zbieg okoliczności?

Tak, to tylko zbieg okoliczności i nie powinieneś na tym polegać, ponieważ nie jest to częścią umowy programowej. Na przykład identyfikatory procesów i wątków systemu Windows 95 nie zawsze były wielokrotnościami czterech. (Dla porównania, powód, dla którego uchwyty jądra są zawsze wielokrotnością czterech, jest częścią specyfikacji i będzie zagwarantowane w dającej się przewidzieć przyszłości).

Identyfikatory procesów i wątków to wielokrotności czterech jako efekt uboczny ponownego użycia kodu. Ten sam kod, który przydziela uchwyty jądra, służy również do przydzielania identyfikatorów procesów i wątków. Ponieważ uchwyty jądra są wielokrotnością czterech, również identyfikatory procesów i wątków. Jest to szczegół implementacji, więc nie pisz kodu, który się na nim opiera. Mówię ci tylko, żebyś zaspokoił swoją ciekawość.

Źródło Dlaczego identyfikatory procesów i wątków są wielokrotnościami czterech?


Dlaczego UCHWYTY jądra są zawsze wielokrotnością czterech?

Nie bardzo dobrze wiadomo, że dolne dwa bity UCHWYTÓW jądra są zawsze zerowe; innymi słowy, ich wartość liczbowa jest zawsze wielokrotnością 4. Zauważ, że dotyczy to tylko UCHWYTÓW jądra; nie dotyczy pseudo-uchwytów ani żadnego innego typu uchwytu (uchwyty UŻYTKOWNIKA, uchwyty GDI, uchwyty multimedialne ...) Uchwyty jądra są rzeczami, które można przekazać do funkcji CloseHandle.

Dostępność dwóch ostatnich bitów jest ukryta w pliku nagłówkowym 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

To, że przynajmniej dolny bit UCHWYTÓW jądra jest zawsze równy zero, wynika z funkcji GetQueuedCompletionStatus, która wskazuje, że można ustawić dolny bit uchwytu zdarzenia, aby pominąć powiadomienie portu zakończenia. Aby to zadziałało, dolny bit zwykle musi wynosić zero.

Informacje te nie są przydatne dla większości autorów aplikacji, którzy powinni nadal traktować UCHWYTY jako nieprzejrzyste wartości. Osoby zainteresowane bitami znaczników to osoby, które implementują biblioteki klas niskiego poziomu lub owijają obiekty jądra w większe ramy.

Źródło Dlaczego UCHWYTY jądra są zawsze wielokrotnością czterech?


Dalsza lektura


DavidPostill
źródło
3
Jeden cytat mówi: „nie powinieneś na nim polegać, ponieważ nie jest to częścią umowy programowej”, ale następne twierdzenia ntdef.h mówią, że bity są „dostępne do wykorzystania przez kod aplikacji jako bity znacznika”. Dokumentacja w publicznym pliku nagłówkowym jest tak blisko „umowy programowej”, jak to tylko możliwe, więc pierwsze roszczenie jest nieprawidłowe.
BlueRaja - Danny Pflughoeft
2
@BlueRaja, „Niezbyt dobrze wiadomo, że dolne dwa bity UCHWYTÓW jądra są zawsze zerowe; innymi słowy, ich wartość liczbowa jest zawsze wielokrotnością 4. ” Kod w ntdef.h dotyczy również innych rodzajów uchwytów (Uchwyty UŻYTKOWNIKA, uchwyty GDI, uchwyty multimedialne ...)
DavidPostill
37
@BlueRaja: uchwyty jądra są wielokrotnością czterech, a to jest umowne, więc możesz na nim polegać; identyfikatory procesów (które są nie takie same, jak obsługuje proces), zamiast tego stało się być wielokrotnością czterech, ale to po prostu szczegółów wdrażania, więc nie należy na niej polegać.
Matteo Italia,
6
@BlueRaja Myślę, że Raymond powiedziałby ci, że każdy, kto napisał dokumentację, patrzył na świat przez szklanki w kolorze jądra, a zatem odnosił się tylko do uchwytów jądra, a nie do innych uchwytów.
CodesInChaos
1
@ Mehrdad: no cóż, uchwyty USER i GDI zwykle nie są nazywane uchwytami „jądra” (chociaż są generowane przez komponenty działające w tak zwanym trybie jądra).
Matteo Italia,