Jde*_*eBP 19
Unices 很久以前就停止使用交换了。自 System V R2V5 和 4.0BSD 以来,它们一直是按需分页操作系统。交换进程,原样,用于执行进程交换操作。它用于交换整个进程——包括所有内核空间进程的数据结构——输出到磁盘并再次交换它们。它会被内核定期唤醒,并会扫描进程表以确定哪些换出并准备运行的进程可以换入以及哪些换入但处于睡眠状态的进程可以换掉。从 1980 年代开始,任何关于 Unix 的教科书都会更详细地介绍这一点,包括交换算法。但它在很大程度上与按需分页的 Unices 无关,即使他们保留了旧的交换机制好几年了。(BSD 非常努力地避免交换,例如支持分页。)
进程#0 是系统中的第一个进程,由内核手工制作。它fork()
是进程 1,第一个用户进程。它除此之外的其他功能取决于操作系统实际上是什么 Unix。如前所述,FreeBSD 5.0 之前的 BSD 保留了旧的交换机制,进程 #0scheduler()
在完成系统初始化后简单地放入内核中的交换代码,即函数。系统 V 大体相同,除了进程 #0 通常被命名sched
而不是swapper
. (名称几乎是任意选择。)事实上,大多数(可能是所有)Unices 都有一个(大部分未使用的)旧交换机制,作为进程 #0 存在。
传统上,Linux 与 Unices 有所不同,其中进程 #0 是空闲进程,正在运行cpu_idle()
. 它只是在无限循环中什么都不做。它的存在使得有总是准备好被调度的任务。
即使这是一个过时的描述。1980 年代末和 1990 年代初是多线程操作系统的出现,因此进程 #0 变成了简单的系统进程。在旧的单线程 Unices 的世界中,只能通过fork()
ing 进程来获得单独的执行流来执行连续的内核任务。所以所有的内核任务(例如 FreeBSD 系统上的vmdaemon
, pagedaemon
, pagezero
, bufdaemon
, syncer
, ktrace
, 等等)都是低编号进程,fork()
在它fork()
ed之后由进程 #0 edìnit
. 在多线程 Unices 中,为完全在内核空间中运行的东西创建一个全新的进程上下文是没有意义的,并且不需要地址空间、文件描述符表等等。所以所有这些任务都变成了(本质上)线程,共享单个系统进程的地址空间。
一路上,几个Unices终于失去了旧的交换机制,他们正在尽最大努力避免使用。OpenBSD 的初始化代码现在只是简单地放入一个while(1) tsleep(…);
循环中,例如,在任何地方都没有交换机制。
所以现在Unix 上的进程 #0 是系统进程,它有效地持有许多内核线程做很多事情,从页出操作,到文件系统缓存刷新和缓冲区清零,到没有其他东西运行时空闲.
进程 0 是一个特殊的进程(称为交换器或空闲进程),它在系统空闲时运行,即没有其他进程被调度。它是唯一可以调用idle()
系统调用的进程。
这是要产生的第一个进程,然后它会创建init
(PID 1) 来启动其他进程。
root 1 0 /sbin/init
Run Code Online (Sandbox Code Playgroud)
您也可以检查man idle
。
另请参阅:了解 Linux 内核 - 进程调度