如果计算机从0开始计数,为什么init进程的pid为1?


27

放在体内没有太多。


18
pid0先后为特殊的意义kill(2)系统调用它意味着自己waitpid(2)它意味着我的进程组的任何过程至少。更不用说fork()返回0意味着我们处于孩子之中。
斯特凡Chazelas

1
您应该将其发布为答案
Jonathan Muller 2013年

3
零会导致大多数CPU的状态寄存器中的标志在加载到寄存器中时自动设置,从而允许在其上进行分支,而无需专门比较/测试它。因此,它非常用作“前哨”值,即在此处表示“无效”,“数据结尾”或“特殊情况”的值。因此,即使计算机从0开始计数,在许多情况下,1还是所讨论的应用程序或数据结构的第一个有效值。
LawrenceC

4
旁注:计算机不会从零开始计数。许多编程语言,我相信所有机器语言都使用偏移量,而其他人(和大多数人类)则使用索引,但是无论如何,计数就是计数。具有两个元素的数组有两个元素(对它们进行计数),无论您的语言是通过偏移量还是通过索引引用它们。
jthill 2013年

这可能是与编程的基本范例相反的情况:程序员对特殊标志值(零,负一)的引力胜过基于零的编号系统的倾向性较小。
迈克尔

Answers:


29

进程需要有一个父级(PPID)。尽管不是真正的进程,但内核仍在手工制作至少init之类的实际进程,并为其赋予进程ID0。根据操作系统的不同,它可能会或可能不会在ps输出中显示为进程,但始终显示作为PPID:

例如在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]
...

在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
...

还要注意的是PID 0(以及-1与此有关的其他负值)有不同的含义取决于什么功能使用他们喜欢的killforkwaitpid

最后,虽然该init过程通常使用pid来指定#1,但像Solaris区域那样使用OS级虚拟化时,情况就不再如此,因为可以init运行多个:

$ 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

5

有两个任务具有特殊的进程ID:swapper或sched的进程ID为0,并负责分页,就像前面示例中提到的jlliagre一样,它实际上是内核的一部分,而不是普通的用户模式进程。

进程ID 1通常是初始化进程,主要负责启动和关闭系统。最初,进程ID 1并没有通过任何技术措施专门保留给init:它只是将该ID作为内核调用的第一个进程的自然结果。较新的Unix系统通常具有可见为“进程”的附加内核组件,在这种情况下,PID 1被主动保留用于初始化进程,以保持与旧系统的一致性。


4

通常,0通常用于表示“空引用”。这意味着即使存在0值,也可能不使用它,因为您希望0表示特殊值。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.