init 进程:所有进程的祖先?

Mat*_*ose 29 linux process init

我一直都知道 init 进程是所有进程的祖先。为什么进程 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]
Run Code Online (Sandbox Code Playgroud)

Gil*_*il' 35

首先,“祖先”与“父母”不同。祖先可以是父级的父级……父级的父级,内核只跟踪一级。然而,当一个进程死亡时,它的子进程被 init 接收,所以在典型的系统上你会看到很多父进程为 1 的进程。

现代 Linux 系统还具有一些执行内核代码的进程,但就调度而言,它们作为用户进程进行管理。(它们不遵守通常的内存管理规则,因为它们正在运行内核代码。)这些进程都是由kthreadd(它是内核线程的初始化)产生的。您可以通过它们的父进程 ID (2) 来识别它们,或者通常通过ps在方括号中列出它们的名称或/proc/2/exe无法读取(通常是指向进程可执行文件的符号链接)的事实来识别它们。

进程 1 ( init) 和 2 ( kthreadd) 在启动时由内核直接创建,因此它们没有父进程。在其 ppid 字段中使用值 0 来表示这一点。将 0 视为此处的“内核本身”。

Linux 还为内核提供了一些工具来启动用户进程,在某些情况下,这些进程的位置通过sysctl 参数指示。例如,内核可以通过调用kernel.modprobesysctl 值中的程序来触发模块加载事件(例如,当发现新硬件时,或首次使用某些网络协议时)。当程序转储核心时,内核调用由kernel.core_patternif any指示的程序。

  • 所以`init`是所有`用户线程`的“祖先”,而`[kthreadd]`是所有`内核线程`的“父”,对吧?谢谢! (2认同)
  • @NanXiao 大多数情况下,是的。正如我在上一段中提到的,内核启动用户进程还有一些其他方法,例如,当程序转储核心时,在“kernel.core_pattern”中列出的程序。在典型的系统上,您不会看到它们,因为这些进程往往会快速完成其工作,然后退出。 (2认同)