Чому немає ідентичних ідентифікаторів процесу Windows?


160

Існує багато способів вивчення ідентифікаторів процесів у Windows.

Наприклад, за допомогою команди PowerShell:

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

Ми бачимо такий вихід:

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

Усі ідентифікатори процесу є парними числами, і, крім того, вони є кратними 4 .

У жодній версії Windows, яка базується на Windows NT, немає непарних ідентифікаторів процесу.

У чому причина цього?


6
Можливо, цікаво: Деякі відомості про Linux - justskins.com/forums/why-are-process-ids-204416.html
Дейв

13
Дійсно, їх немає. Це дивно.
AndreKR

Відповіді:


168

"Чому немає ідентичних ідентифікаторів процесів Windows?"

Той самий код, який виділяє ручки ядра, також використовується для розподілу ідентифікаторів процесу та потоку. Оскільки ручки ядра є кратними чотирма, то також і ідентифікатори процесів і потоків.


Чому ідентифікатори процесу і потоків кратні чотирма?

В операційних системах на базі Windows NT ідентифікатори процесів і потоків завжди бувають кратними чотирма. Це просто збіг?

Так, це просто збіг обставин, і ви не повинні покладатися на нього, оскільки це не є частиною договору програмування. Наприклад, ідентифікатори процесів і потоків Windows 95 не завжди були кратними чотирма. (Для порівняння, причина того, що ручки ядра завжди кратні чотирьом, є частиною специфікації і буде гарантована в осяжному майбутньому.)

Ідентифікатори процесу та потоку є кратними чотирма як побічний ефект повторного використання коду. Той самий код, який виділяє ручки ядра, також використовується для розподілу ідентифікаторів процесу та потоку. Оскільки ручки ядра є кратними чотирма, то також і ідентифікатори процесів і потоків. Це деталізація реалізації, тому не пишіть код, який покладається на неї. Я просто кажу вам, щоб задовольнити вашу цікавість.

Джерело Чому ідентифікатори процесу і потоку кратні чотирма?


Чому РУЧКИ ядра завжди кратні чотирма?

Не дуже добре відомо, що два нижні біта HANDLEs ядра завжди дорівнюють нулю; Іншими словами, їх числове значення завжди кратне 4. Зверніть увагу, що це стосується лише РУЧКІВ ядра; це не стосується псевдо-ручок або будь-якого іншого типу ручок (USER-ручки, GDI-ручки, мультимедійні ручки ...) Ручки ядра - це речі, які ви можете перейти до функції CloseHandle.

Наявність двох нижчих бітів закопується у файлі заголовка 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

Що принаймні нижній біт HANDLEs ядра завжди дорівнює нулю, мається на увазі функція GetQueuedCompletionStatus, яка вказує на те, що ви можете встановити нижній біт ручки події для придушення сповіщення про порт завершення. Для того, щоб це працювало, нижній біт зазвичай повинен дорівнювати нулю.

Ця інформація не є корисною для більшості авторів програм, які повинні продовжувати трактувати HANDLE як непрозорі значення. Люди, які були б зацікавлені у бітах тегів, - це ті, хто реалізує бібліотеки класів низького рівня або обертає об’єкти ядра всередині більшого фрейму.

Джерело Чому РУЧКИ Ядра завжди кратні чотирма?


Подальше читання



3
В одній цитаті сказано, що "ви не повинні покладатися на нього, оскільки він не є частиною контракту на програмування", але наступна заява ntdef.h говорить, що біти "доступні для використання кодом програми як біти тегів". Документація у загальнодоступному файлі заголовка приблизно наближена до "контракту на програмування", наскільки ви можете отримати, тому перша претензія є неправильною.
BlueRaja - Danny Pflughoeft

2
@BlueRaja, "Не дуже добре відомо, що два нижні біти HANDLEs ядра завжди дорівнюють нулю; іншими словами, їх числове значення завжди кратне 4. " Код в ntdef.h застосовується і до інших видів ручок (Ручки USER, ручки GDI, мультимедійні ручки ...)
DavidPostill

37
@BlueRaja: ручки ядра кратні чотирьом, і це договірно, тому ви можете покластися на нього; ідентифікатори ідентифікаторів процесів (які не збігаються з ручками процесів), натомість бувають кратними чотирьом, але це лише деталі реалізації, тому не варто покладатися на них.
Маттео Італія

6
@BlueRaja Я думаю, що Реймонд сказав би вам, що той, хто писав документацію, дивився на світ через окуляри кольору ядра і, таким чином, посилався лише на ручки ядра, а не на інші види ручок.
CodesInChaos

1
@Mehrdad: ну ручки USER та GDI зазвичай не називаються ручками "ядра" (хоча вони генеруються компонентами, що працюють у так званому режимі ядра).
Маттео Італія
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.