3

My Google-fu has failed me!

On Linux, the process with the lowest PID is init with PID 1, since it is the first process that gets started after the kernel loads, and is responsible for starting all other processes.

pi@raspberry:~ $ ps -ef --sort=pid | head -n 5
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 Jan22 ?        00:02:20 /sbin/init
root         2     0  0 Jan22 ?        00:00:00 [kthreadd]
root         3     2  0 Jan22 ?        00:05:54 [ksoftirqd/0]
root         5     2  0 Jan22 ?        00:00:00 [kworker/0:0H]

On Windows, the process with the lowest PID is System with PID 4.

PS C:\Users\msbob> Get-Process | Sort-Object Id | Select -First 5

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
      0       0        0         24     0               0 Idle
    755       0      144        844     4               4 System
     32       1      556       1268     4             388 smss
    521      82   139796     124204   390     6.07    424 iexplore
    661      12     2268       4728    49             604 csrss

Why is System PID 4 on Windows, not PID 1?

Hydraxan14
  • 658
  • 6
  • 15

1 Answers1

9

You'll notice that all of the PIDs are divisible by 4. 4 is therefore the first PID available after 0 (which is the Idle process).

For the reason that that is true, see this MSDN post by Raymond Chen:

Process and thread IDs are multiples of four as a side-effect of code re-use. The same code the allocates kernel handles is also used to allocate process and thread IDs. Since kernel handles are a multiple of four, so too are process and thread IDs.

Note, though, that process IDs are not actually usable handle values for those processes. The numbers are just generated by the same algorithm.

And for the reason that kernel handles are always divisible by four... Raymond Chen to the rescue again!

The availability of the bottom two bits is buried in the ntdef.h header file:

// Low order two bits of a handle are ignored by the system and available 
// for use by application code as tag bits.  The remaining
// and used to store a serial number and table index.    
#define OBJ_HANDLE_TAGBITS  0x00000003L

(For those not familiar with binary numbers: A positive binary integer with its two low-order bits zero is always divisible by four, just like a decimal number that ends in "00" is always divisible by 100.)

So... a whimsical answer is that the first PID really is "1". It's just that Task Manager, et al, don't know that in the internal form it's shifted left by two bits. :)

bot47
  • 1,802
  • 3
  • 21
  • 35
Jamie Hanrahan
  • 23,140
  • 6
  • 63
  • 92