Processes need to have a parent (PPID). The kernel, despite not being a real process, is nevertheless handcrafting some real processes like at least init, and is giving itself the process ID 0. Depending on the OS it might or might not be displayed as a process in ps
output but is always displayed as a PPID:
eg on Linux:
$ ps -ef|head
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 09:09 ? 00:00:00 /sbin/init
root 2 0 0 09:09 ? 00:00:00 [kthreadd]
root 3 2 0 09:09 ? 00:00:00 [ksoftirqd/0]
...
on Solaris:
$ ps -ef|head
UID PID PPID C STIME TTY TIME CMD
root 0 0 0 Oct 19 ? 0:01 sched
root 5 0 0 Oct 19 ? 11:20 zpool-rpool1
root 1 0 0 Oct 19 ? 0:13 /sbin/init
root 2 0 0 Oct 19 ? 0:07 pageout
root 3 0 1 Oct 19 ? 117:10 fsflush
root 341 1 0 Oct 19 ? 0:15 /usr/lib/hal/hald --daemon=yes
root 9 1 0 Oct 19 ? 0:59 /lib/svc/bin/svc.startd
...
Note also that pid 0
(and -1
and other negative values for that matter) have different meanings depending on what function use them like kill
, fork
and waitpid
.
Finally, while the init
process is traditionally given pid #1
, this is no more the case when OS level virtualization is used like Solaris zones, as there can be more than one init
running:
$ ps -ef|head
UID PID PPID C STIME TTY TIME CMD
root 4733 3949 0 11:07:25 ? 0:26 /lib/svc/bin/svc.configd
root 4731 3949 0 11:07:24 ? 0:06 /lib/svc/bin/svc.startd
root 3949 3949 0 11:07:14 ? 0:00 zsched
daemon 4856 3949 0 11:07:46 ? 0:00 /lib/crypto/kcfd
root 4573 3949 0 11:07:23 ? 0:00 /usr/sbin/init
netcfg 4790 3949 0 11:07:34 ? 0:00 /lib/inet/netcfgd
root 4868 3949 0 11:07:48 ? 0:00 /usr/lib/pfexecd
root 4897 3949 0 11:07:51 ? 0:00 /usr/lib/utmpd
netadm 4980 3949 0 11:07:54 ? 0:01 /lib/inet/nwamd
init is not "spawned" (as a child process), but rather exec
'd like this:
# Boot the real thing.
exec switch_root /mnt/root /sbin/init
exec
replaces the entire process in place. The final init is still the first process (pid 1), even though it was preceded with those in the Initramfs.
The Initramfs /init
, which is a Busybox shell script with pid 1, exec
s to Busybox switch_root
(so now switch_root
is pid 1); this program changes your mount points so /mnt/root
will be the new /
.
switch_root
then again exec
s to /sbin/init
of your real root filesystem; thereby it makes your real init system the first process with pid 1, which in turn may spawn any number of child processes.
Certainly it could just as well be done with a Python script, if you somehow managed to bake Python into your Initramfs. Although if you don't plan to include busybox anyway, you would have to painstakingly reimplement some of its functionality (like switch_root
, and everything else you would usually do with a simple command).
However, it does not work on kernels that do not allow script binaries (CONFIG_BINFMT_SCRIPT=y
), or rather in such a case you'd have to start the interpreter directly and make it load your script somehow.
Best Answer
Because a process that dies (crashes, presumably) soon after starting is broken, and has to be fixed. Wasting resources on it makes no sense (and the crashing process could do damage, like leaving mangled files behind).