【问题标题】:Does the UNIX init process always runUNIX init 进程是否总是运行
【发布时间】:2016-04-22 15:46:40
【问题描述】:

我有一个关于 UNIX 中的 init 进程如何工作的问题。据我了解,init 进程是第一个启动的,然后其他进程分叉它。

假设我们启动 init 进程,然后 fork 一个子进程,我们用一个新程序调用 exec ,这恰好导致子进程等待一些 I/O 输入。现在父初始化进程可以等待子进程,但如果它这样做了,那么就没有其他进程可以运行了。相反,如果 init 进程不等待而是陷入等待循环或其他情况,那么当子进程恢复时,父进程现在占用处理器时间什么也不做。

解决此问题的最佳方法是什么? init 进程是否应该简单地总是运行一个无限循环并且我们不担心资源浪费?或者有没有更好的方法。

任何帮助将不胜感激, 本

【问题讨论】:

    标签: unix init process-management


    【解决方案1】:

    进程 1 绝不能退出; Unix 的许多(全部?)实现会强制系统崩溃。

    然而,进程 1需要做更多的事情(我假设内核在将控制权转移到用户空间之前在控制台上打开 fds 0、1 和 2 - 检查如果你真的要自己写init,你的内核文档以及引导环境的其他细节):

    #include <sys/types.h>
    #include <sys/wait.h>
    #include <unistd.h>
    #include <stdio.h>
    
    int main(void)
    {
        pid_t child = fork();
        if (child == -1) {
            perror("init: fork");
            return 1;
        }
        if (child == 0) {
            execl("/etc/rc", "/etc/rc", (char*)0);
            perror("/etc/rc");
            return 1;
        }
        for (;;)
            wait(0);
    }
    

    在启动/etc/rc 之后,它确实进入了一个无限循环,一遍又一遍地调用wait,并丢弃结果。但是wait 是一个阻塞 系统调用。每次调用它时,内核都会将 CPU 从进程 1 中取出,并将其交给一个有有用工作要做的进程; wait 只会在有退出的孩子要报告时返回。 (如果没有个进程需要做有用的工作,CPU 将进入低功耗“睡眠”状态,直到某些外部事件,例如键盘上的人打字或网络数据包到达,给正在运行的进程一些工作要做。)

    有了这个最小的init,完全是/etc/rc 负责启动所有需要的程序以使计算机做一些有用的事情,并且这些程序有责任在需要时继续运行;如果它应该通过除此之外的每个进程都退出,它将永远在wait 中休眠。更复杂的实现会做得更多,例如如果网络服务器崩溃,则重新启动它们。

    【讨论】:

      【解决方案2】:

      对此有一个解决方案:SIGCHLD。这是一个可以在孩子改变其状态(停止或退出)时传递给父母的信号。因此,父母可以进入睡眠状态(例如sigpausesigsuspend)并在孩子终止时被中断,然后父母运行适当的信号处理程序来调用wait-family 函数之一。

      【讨论】:

      • 所以我认为wait 系统调用只有在子进程终止并且SIGCHILD 信号与wait 机制不同时才会恢复父进程,这是否正确?
      • wait 用于:获取终止子进程的退出状态,并将子进程从进程列表中移除(无僵尸进程)。 wait 不会恢复任何内容。 wait 可以同步等待子终止,SIGCHILD 是一个异步事件,用于警告子终止。
      【解决方案3】:

      在init 启动期间我不会担心资源问题。您的服务器正在启动并且未用于其预期目的,因此在此期间对其没有性能需求。

      我从来没有见过一个在启动过程中接受标准输入的过程,尽管如果你想写一个是可能的。我知道初始化脚本可以用依赖项编写,这取决于您使用的发行版以及启动过程的确切内容(upstart、system V init 等)。但默认情况下,它们按照 init 使用的顺序以同步方式运行。我不确定如何阻止同步过程......等待输入会影响系统。最有可能的是,它会这样做......停止并等待输入,然后再继续。

      【讨论】:

        【解决方案4】:

        init 进程确实运行了一个无限循环,但这不会使用任何重要的资源,因为它是由中断驱动的。它只是等待进程死亡或其他信号发送给它。在等待间隔期间,init 使用了零个 CPU 周期。

        【讨论】:

          猜你喜欢
          • 2012-02-25
          • 1970-01-01
          • 2016-02-09
          • 1970-01-01
          • 2019-06-11
          • 2011-08-06
          • 2013-09-20
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多