What is PID 0?

What is the very first PID (Process IDentifier) running on your (Unix-like) operating system? Well, as any professor will answer to you, it is the init process that runs on PID number one. Then comes systemd, so, at least in many Linux distributions, the correct answer is it is the systemd process that runs on PID number one. Unless you discover there could be also a pid 0!

Linux

TL;DR: in Linux it seems there is no PID 0 process, so you can quickly get back to your life (or read more on).

% uname -s -r -v
Linux 6.2.0-33-generic #33-Ubuntu SMP PREEMPT_DYNAMIC Tue Sep  5 14:49:19 UTC 2023

% ps -p 0
error: process ID out of range


% ps -p 1
    PID TTY          TIME CMD
      1 ?        00:00:01 systemd

% pstree
systemd─┬─ModemManager───3*[{ModemManager}]
        ├─NetworkManager───3*[{NetworkManager}]
        ├─accounts-daemon───3*[{accounts-daemon}]



It is interesting to use pstree that has the ability to display parents and child of a given pid.

% pstree -p 0
?()-+-kthreadd(2)-+-UVM Tools Event Queue(682)
    |             |-UVM deferred release queue(663)
    |             |-UVM global queue(662)
    |             |-acpi_thermal_pm(88)
    |             |-ata_sff(77)
    |             |-blkcg_punt_bio(74)
    |             |-charger_manager(111)
    |             |-cpuhp/0(19)
    |             |-cpuhp/1(20)
    |             |-cpuhp/2(26)
    |             |-cpuhp/3(32)
    |             |-cpuhp/4(38)
    |             |-cpuhp/5(44)
    |             |-cpuhp/6(50)
...
    |             `-zswap-shrink(106)
     `-systemd(1)-+-ModemManager(1095)-+-{ModemManager}(1106)


So as you can see, effectively there is a kind of process 0 that is the parent even of systemd.

FreeBSD

On FreeBSD there is a pid 0 process!

% uname -s -r -v
FreeBSD 13.2-RELEASE-p3 FreeBSD 13.2-RELEASE-p3 GENERIC

% ps -p 0
PID TT  STAT    TIME COMMAND
  0  -  DLs  0:00.63 [kernel]

% pstree
-+= 00001 root /sbin/init
 |--= 00441 root dhclient: system.syslog (dhclient)
 |--= 00444 root dhclient: em0 [priv] (dhclient)
 |--= 00522 _dhcp dhclient: em0 (dhclient)
 |--= 00528 root /sbin/devd




Interesting, isn’t it? While the system is effectively reporting init as the process parent of every other process in the system (see pstree output), there is effectively a process with PID 0 name [kernel]. The status of the process, DLs means that the process is locked (L) on waiting for disk (D) and is a leader (s). More information can be obtained asking about threads:

% ps -p 0 -c -H
PID TT  STAT    TIME COMMAND
  0  -  DLs  0:20.93 kernel/swapper
  0  -  DLs  0:00.00 kernel/softirq_0
  0  -  DLs  0:00.05 kernel/if_io_tqg_0
  0  -  DLs  0:01.65 kernel/if_config_tqg_0
  0  -  DLs  0:00.00 kernel/linuxkpi_irq_wq
  0  -  DLs  0:00.00 kernel/aiod_kick taskq
  0  -  DLs  0:00.00 kernel/inm_free taskq
  0  -  DLs  0:00.00 kernel/thread taskq
  0  -  DLs  0:00.00 kernel/kqueue_ctx taskq
  0  -  DLs  0:00.00 kernel/in6m_free taskq
  0  -  DLs  0:00.00 kernel/pci_hp taskq
  0  -  DLs  0:00.00 kernel/linuxkpi_short_wq_0
  0  -  DLs  0:00.00 kernel/linuxkpi_short_wq_1
  0  -  DLs  0:00.00 kernel/linuxkpi_short_wq_2
  0  -  DLs  0:00.00 kernel/linuxkpi_short_wq_3
  0  -  DLs  0:00.00 kernel/linuxkpi_long_wq_0
  0  -  DLs  0:00.00 kernel/linuxkpi_long_wq_1
  0  -  DLs  0:00.00 kernel/linuxkpi_long_wq_2
  0  -  DLs  0:00.00 kernel/linuxkpi_long_wq_3
  0  -  DLs  0:00.00 kernel/firmware taskq
  0  -  DLs  0:00.00 kernel/crypto
  0  -  DLs  0:00.00 kernel/acpi_task_0
  0  -  DLs  0:00.00 kernel/acpi_task_1
  0  -  DLs  0:00.00 kernel/acpi_task_2
  0  -  DLs  0:00.00 kernel/CAM taskq




So the pid 0 is low-level stuff (what a definition!), meaning it is the kernel running.

Conclusions

There is pretty much always a PID 0, but sometimes the tooling prevent you to see it. While I’ve shown that FreeBSD has one, as well as OpenBSD, even Linux does have a PID 0 process that is usually the kernel related stuff running.

The article What is PID 0? has been posted by Luca Ferrari on September 27, 2023