我一直了解到,初始化过程是所有过程的始祖。为什么进程2的PPID为0?
$ ps -ef | head -n 3
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 May14 ? 00:00:01 /sbin/init
root 2 0 0 May14 ? 00:00:00 [kthreadd]
我一直了解到,初始化过程是所有过程的始祖。为什么进程2的PPID为0?
$ ps -ef | head -n 3
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 May14 ? 00:00:01 /sbin/init
root 2 0 0 May14 ? 00:00:00 [kthreadd]
Answers:
首先,“祖先”与“父母”不是一回事。祖先可以是父级的父级…父级的父级,并且内核仅跟踪一个级别。但是,当进程死亡时,其子进程将被init所采用,因此您将在典型系统上看到许多父进程为1的进程。
现代Linux系统还具有一些执行内核代码的进程,但是就调度而言,它们作为用户进程进行管理。(由于它们正在运行内核代码,因此它们不遵循通常的内存管理规则。)这些进程都是由kthreadd
(它是内核线程的初始化)产生的。您可以通过它们的父进程ID(2)来识别它们,通常可以通过ps
在方括号中列出它们的名称来识别它们,也可以通过/proc/2/exe
(通常是到该过程可执行文件的符号链接)来识别它们。
进程1(init
)和2(kthreadd
)由内核在启动时直接创建,因此它们没有父级。在其ppid字段中使用值0表示这一点。在这里,将0视为“内核本身”。
Linux还为内核提供了一些启动内核进程的功能,这些进程在某些情况下通过sysctl参数指示其位置。例如,内核可以通过在kernel.modprobe
sysctl值中调用程序来触发模块加载事件(例如,发现新硬件或首次使用某些网络协议时)。当程序转储内核时,内核将调用指示的程序(kernel.core_pattern
如果有)。
kernel.core_pattern
程序转储内核时列出的程序。在典型的系统上,您将看不到它们,因为这些过程往往会很快完成其工作,然后退出。
init
是所有的“祖先”user threads
,同时[kthreadd ]
是所有的“家长”kernel threads
,对不对?谢谢!