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

process windows

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は存在しません

その理由は何なのでしょうか?

  163  Peter Hahndorf  2015-07-06


ベストアンサー

“なぜWindowsのプロセスIDがないのか?”

カーネルハンドルを割り当てるのと同じコードは、プロセス ID とスレッド ID を割り当てるのにも使われます。カーネルハンドルは 4 の倍数なので、プロセス ID とスレッド ID も同様です


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

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

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

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

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


なぜカーネルHANDLEは常に4の倍数なのですか?

あまり知られていませんが、カーネルの HANDLE の下位 2 ビットは常にゼロです。 これはカーネルの HANDLE にのみ適用され、疑似ハンドルや他のタイプのハンドル (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

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

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

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


Further reading


167  DavidPostill  2015-07-06


タイトルとURLをコピーしました