为什么 kthread 有 pid 2 而 systemd 有 PID 1?

why kthread have pid 2 and systemd have PID 1?

在 systemd 环境中,当我执行 ps -auxf 时,我看到 kthread 的 PID 为 2,而 systemd 的 PID 为 1。

那么,谁将 PID 2 分配给 kthread,为什么当 kthread 调用 systemd 时它获得 PID 2?

我不认为 kthreadd 开始 init(在你的情况下符号链接到 systemd)。

init是由内核初始化启动的。 kthreadd 紧接着开始。请参阅此 kernel threads wikipage, and, for Linux 4.2, its file init/main.c、函数 rest_init,在第 397 行附近,您会在其中看到:

/*
 * We need to spawn init first so that it obtains pid 1, however
 * the init task will end up wanting to create kthreads, which, if
 * we schedule it before we create kthreadd, will OOPS.
 */
kernel_thread(kernel_init, NULL, CLONE_FS);
numa_default_policy();
pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);

所以kthreadd不是开始init,但是两者都是在被调度之前在内核中启动的,所以在开始它们之前执行.

静态 kernel_init 函数(init/main.c 的第 930 - 975 行)具有显着的特点:

if (execute_command) {
    ret = run_init_process(execute_command);
    if (!ret)
        return 0;
    panic("Requested init %s failed (error %d).",
          execute_command, ret);
}
if (!try_to_run_init_process("/sbin/init") ||
    !try_to_run_init_process("/etc/init") ||
    !try_to_run_init_process("/bin/init") ||
    !try_to_run_init_process("/bin/sh"))
    return 0;

因此正在设置 init 进程(à la execve(2)...)并已硬连线 /sbin/init 等...

init process has pid 1 for ages (since primordial Unix of the 1970s, and also in old Linux 1.x kernels without kernel threads). It is a strong Unix convention (on which probably a lot of software depends). You can use systemd as your init process, but you could also use sysvinit or simply bash (it is sometimes useful to pass init=/bin/bash to the kernel thru GRUB for repairing purposes) or something else (e.g. runit)