关于UNIX中的init进程是如何工作的,我有一个问题。据我所知,init进程首先启动,然后是其他进程分叉它。
比如说,我们启动init进程,然后用一个新的程序对一个子进程进行分叉,然后调用exec,这个程序碰巧会导致子进程等待一些I/O输入。现在父init进程可以等待子进程,但是如果它这样做了,那么就没有其他进程要运行了。相反,如果init进程不等待,而是陷入等待循环或其他情况,那么当子进程恢复时,父进程现在占用处理器时间,什么也不做。
处理这个问题的最佳方法是什么?init进程应该始终运行无限循环,而不必担心浪费的资源吗?或者有没有更好的方法。
任何帮助都会很感激的,本
发布于 2017-02-27 17:06:50
进程1绝不能退出;很多(全部?)Unix的实现会迫使系统崩溃。
但是,process 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
里。更复杂的实现将完成更多工作,例如,如果网络服务器崩溃,就重新启动网络服务器。
发布于 2016-04-23 03:34:43
有一个解决方案:SIGCHLD
。当一个子节点改变其状态(停止或退出)时,它是一个可以传递给父级的信号。因此父函数可以进入休眠状态(例如,sigpause
,sigsuspend
),并且在子节点终止时会被中断,然后父进程运行一个适当的信号处理程序来调用wait
-family函数之一。
发布于 2016-04-22 07:56:20
在启动时,我不会担心资源问题。您的服务器正在启动,而不是用于它的预期目的,因此在这段时间内没有对它的性能要求。
我从未见过在引导过程中编写用于接受标准输入的进程,尽管如果您想编写一个过程,这是可能的。我知道init脚本可以使用依赖项编写,具体取决于您使用的发行版以及引导过程(upstart、system init等)。但在默认情况下,它们按照init使用的顺序以同步方式运行。我不确定阻止输入的同步process...waiting会对系统产生多大影响。最有可能的是,它只执行that....stop并等待输入才能继续。
https://stackoverflow.com/questions/36798208
复制