奇妙なWindowsプロセスIDがないのはなぜですか?


160

WindowsでプロセスIDを調べるには多くの方法があります。

たとえば、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       
...     

すべてのプロセスIDは偶数であり、さらにすべて4の倍数です

Windows NTに基づくWindowsのバージョンには、奇妙なプロセスIDはありません。

この理由は何ですか?


6
おそらく興味深い:Linuxについての詳細-justskins.com/forums/why-are-process-ids-204416.html
Dave

13
確かに何もありません。それは変だ。
-AndreKR

回答:


168

「なぜ奇妙なWindowsプロセスIDがないのですか?」

カーネルハンドルを割り当てる同じコードは、プロセスIDとスレッドIDの割り当てにも使用されます。カーネルハンドルは4の倍数であるため、プロセスおよびスレッドIDも同様です。


プロセスIDとスレッドIDが4の倍数なのはなぜですか?

Windows NTベースのオペレーティングシステムでは、プロセスIDとスレッドIDは常に4の倍数になります。これは単なる偶然ですか?

はい、それは単なる偶然であり、プログラミング契約の一部ではないので、それに頼るべきではありません。たとえば、Windows 95のプロセスIDとスレッドIDは常に4の倍数ではありませんでした。(比較すると、カーネルハンドルが常に4の倍数である理由は仕様の一部であり、当面の間保証されます。)

コードの再利用の副作用として、プロセスIDとスレッドIDは4の倍数です。カーネルハンドルを割り当てるのと同じコードは、プロセスIDとスレッドIDの割り当てにも使用されます。カーネルハンドルは4の倍数であるため、プロセスおよびスレッドIDも同様です。これは実装の詳細なので、それに依存するコードを記述しないでください。私はあなたの好奇心を満たすように言っています。

ソースプロセスIDとスレッドIDが4の倍数なのはなぜですか?


カーネルハンドルが常に4の倍数になるのはなぜですか?

あまり知られていないのは、カーネルハンドルの下位2ビットが常にゼロであることです。つまり、数値は常に4の倍数です。これはカーネルハンドルにのみ適用されることに注意してください。疑似ハンドルやその他のタイプのハンドル(USERハンドル、GDIハンドル、マルチメディアハンドルなど)には適用されません。カーネルハンドルは、CloseHandle関数に渡すことができるものです。

下位2ビットの可用性は、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

少なくともカーネルHANDLEの最下位ビットが常にゼロであることは、GetQueuedCompletionStatus関数によって暗示されます。これは、イベントハンドルの最下位ビットを設定して完了ポート通知を抑制することができることを示します。これが機能するためには、通常、最下位ビットはゼロでなければなりません。

この情報は、HANDLEを不透明な値として扱い続ける必要があるほとんどのアプリケーション作成者には役立ちません。タグビットに興味がある人は、低レベルのクラスライブラリを実装している人、またはより大きなフレームワーク内にカーネルオブジェクトをラップしている人です。

ソースカーネルハンドルが常に4の倍数になるのはなぜですか?


参考文献



3
ある引用文は「プログラミング契約の一部ではないので、これに頼るべきではない」と言っていますが、次の主張ntdef.hは、ビットは「アプリケーションコードでタグビットとして使用できる」と述べています。 パブリックヘッダーファイルのドキュメントは、取得できる限り「プログラミング契約」に近いため、最初の主張は正しくありません。
BlueRaja-ダニーPflughoeft

2
@BlueRaja、「カーネルHANDLEの下位2ビットが常にゼロであることはあまり知られていません。つまり、数値は常に4の倍数です。」ntdef.hのコードは他の種類のハンドルにも適用されます。 (ユーザーハンドル、GDIハンドル、マルチメディアハンドル...)
DavidPostill

37
@BlueRaja:カーネルハンドルは4の倍数であり、これは契約上のものなので、信頼できます。プロセスID(あるいないプロセスのハンドルと同じ)、代わりに、起こるあなたはそれに頼るべきではありませんので、4の倍数になるように、それは単に実装の詳細です。
マッテオイタリア

6
@BlueRajaレイモンドは、ドキュメントを書いた人は誰でもカーネル色のメガネを通して世界を見ているため、他の種類のハンドルではなく、カーネルハンドルのみを参照していると言うと思います。
CodesInChaos

1
@Mehrdad:まあ、USERハンドルとGDIハンドルは通常「カーネル」ハンドルと呼ばれません(ただし、いわゆるカーネルモードで実行されているコンポーネントによって生成されます)。
マッテオイタリア
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.