一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第5天,点击查看活动详情。
运行受限
当CPU虚拟化后,操作系统在许多看似同时运行的作业之间共享CPU,这要求我们设计一些方法来合理的实现虚拟化。自然,有两个方面需要我们仔细考虑,一是性能,如何在开销可接收的情况下实现虚拟化?第二个是控制,我们如何确保操作系统总是能够控制机器资源,而不至于让进程接管机器。这一节我们主要解决第二点。
既然操作系统也是由许多程序组成的,也就是说操作系统本身也是诸多进程的集合。但我们要形成一种共识,普通程序的运行应当受到操作系统的调控,保证其运行受限,防止其做出危害系统软件和硬件的行为。
更具体的说,进程在运行时总是想要占用全部的CPU时间,操作系统如何确保进程不会做任何我们不想让它做的事情,或者说,我们需要一些技术让操作系统:
- 能够在进程想要做不被允许的操作时检测并暂停(终止)它
- 在不占用CPU的情况下也能够切换(终止)普通进程
基于我们对进程的基础认识,我们可以简单描述系统和进程之间的交互关系,如下图所示。接下来我们引入运行受限(LIMITED DIRECT EXECUTION) 这个概念,在下图的基础上增加一些操作。
我们先直接描述一下运行受限协议的流程,操作系统为CPU套上“保护套”,在开机时操作系统初始化trap表并启动中断计时器,让操作系统处于内核模式,普通进程处于受限模式。在某些关键的时间点,例如当一个进程发出一个系统调用,或者一个定时器中断发生时,安排操作系统参与进来,并确保“正确”的事情发生。
这里有三个概念需要进行解释,首先操作系统定义了两种进程状态,内核的和受限的。顾名思义,内核进程就是操作系统进程,受限进程就是收到操作系统管理的普通进程,相对于内核进程,受限进程无法进行IO,申请CPU资源和占用更多内存。这些都需要通过操作系统进行系统调用来协助进行。
trap在表现上是一种由异常情况(例如,断点,非法操作码)引起的同步中断,它一开始就在硬件中初始化,多个trap组成trap table。当触发trap则将进入操作系统进程,也就是内核模式来处理异常,这是我们初次接触硬件协助(hardware support)
中断计时器是一种定期触发trap的机制,在CPU被用户进程占用时,操作系统是无法主动得到进程的控制权的,这时候硬件通过设置中断计时器来让进程每隔一段时间进行一次中断,帮助操作系统能够在一段时间内获得操作进程和进行system call的能力。
说那么多不如直接看流程图,下图展示了在运行受限的前提下,系统在开机时初始化流程,和运行时系统、硬件、进程三者之间的关系
通过这些基础机制,操作系统只需要处理内核操作和切换用时过长进程即可保证其它进程安全的进行。但是,总是有多个进程同时向操作系统请求cpu占用,操作系统该怎么安排,这是系统能否高效运行的保证。
注: 进行system call和context switch的时间成本都非常低,但相对CPU执行速度来说不可忽视。
Based on our observations, the average direct cost of the kernel-level context switch is 0.62\u0016sand the average direct cost of user-level context switch time is 1.18\u0016s.