我对UNIX中的init进程如何工作有疑问。据我所知,init进程是第一个启动,然后其他进程分叉它。
假设我们启动init进程然后fork一个子进程,我们用一个新程序调用exec,这会导致子进程等待一些I / O输入。现在,父init进程可以等待子进程,但如果这样做,那么就没有其他进程可以运行。相反,如果init进程没有等待,而是进入等待循环或者其他什么,那么当子进程恢复时,父进程现在占用处理器时间。
管理此问题的最佳方法是什么? init进程是否应该始终运行无限循环而我们不担心浪费的资源?或者有更好的方法。
非常感谢任何帮助, 本
答案 0 :(得分:1)
有一个解决方案:SIGCHLD
。当孩子改变其状态(停止或退出)时,这是一个可以传递给父母的信号。所以父母可以睡觉(例如sigpause
,sigsuspend
)并且当孩子终止时会被打断,然后父母会运行一个合适的信号处理程序来调用wait
- 家庭之一功能
答案 1 :(得分:0)
我不担心init启动期间的资源。您的服务器正在启动而不是用于它的预期目的,因此在此期间没有性能要求。
我从未见过在启动过程中编写过程以接受标准输入的过程,尽管如果您想编写一个过程,这是可能的。我知道init脚本可以使用依赖项编写,具体取决于您使用的发行版以及启动过程的确切内容(upstart,系统V init等)。但默认情况下,它们以init使用的顺序以同步方式运行。我不确定同步过程如何阻塞......等待输入会影响系统。最有可能的是,它会做到这一点....在继续之前停止并等待输入。
答案 2 :(得分:0)
init进程确实运行了无限循环,但由于它是中断驱动的,因此不使用任何重要资源。它只是等待进程死亡或将其他信号发送给它。在等待间隔期间,init使用零CPU周期。
答案 3 :(得分:0)
进程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
只有在有退出的孩子报告时才会返回。 (如果有 no 进程需要做有用的工作,CPU将进入低功耗“休眠”状态,直到某些外部事件,例如键盘上的人类输入或网络数据包到达,给运行过程一些工作要做。)
使用这个最小init
,完全/etc/rc
有责任启动使计算机做一些有用的事情所需的所有程序,并且这些程序有责任继续运行需要;如果它应该通过除了这个以外的每个进程退出,它将永远睡在wait
。更复杂的实现将做更多,例如如果网络服务器崩溃,请重新启动它们。