博客主页:Skylar Lin
望本文能够给您带来一定的帮助,如果有错误的地方敬请斧正!
新人博主,希望多多支持,还有好多库存和大家分享。
转载需注明出处和原作。
在使用计算机或笔记本时,我们会同时运行多种程序,如浏览器、音乐播放器、微信,等等。实际上,一个正常的系统可能同时会有上百个程序同时在运行;而我们知道计算机的CPU是有限的,这看起来却好似有无数个CPU在工作,究竟是怎么做到的呢?
这其实是操作系统的虚拟化技术(CPU时分共享技术),通过让一个进程只运行一个时间片,然后切换其他进程,从而达到提供多个虚拟CPU的假象。而要实现CPU的虚拟化,操作系统就需要使用一些低层的机制和高级的调度策略。
本文将介绍操作系统实现虚拟化CPU所需要的机制:受限制直接执行(LDE机制)。
在构建虚拟化机制时我们面临着一些挑战:
性能:如何在不增加系统开销的情况下实现虚拟化?
控制权:如何有效地运行进程,同时保留对 CPU 的控制?
操作系统是“资源管理者”,它需要确保程序不做任何我们不希望它做的事,并且需要让一个进程在合适的时候停下来切换到另一个进程,因此,操作系统需要保留对CPU的控制权。
如果没有控制权,一个进程可以简单地无限制运行并接管机器,或访问没有权限的信息。
当一个程序正在运行时,它占据着CPU的使用权,此时我们如何限制程序的行为呢?
我们需要引入一种新的处理器模式,称为用户模式(user mode),在用户模式下运行的代码会受到限制;例如,在用户模式下运行时,进程不能发出 I/O 请求。
与用户模式不同的内核模式(kernel mode),操作系统(或内核)就以这种模式运行;在此模式下,运行的代码可以做它喜欢的任何事情。
如果用户程序想要执行某种特权操作,就必须调用操作系统提供的系统调用(System Call),陷入内核并将特权级提升为内核模式。在内核模式下完成工作后,操作系统调用陷阱返回指令,返回到发起调用的用户程序中,同时将特权级别降低,回到用户模式。
进入内核后,内核如何知道应该执行哪些代码呢?
内核通过在启动时设置陷阱表(trap table),知道了在发生某些异常事件时相对地要运行哪些代码。因此它在特权内核模式下执行时,可以根据需要自由配置机器硬件。
表 6.2 中总结了该协议。我们假设每个进程都有一个内核栈,在进入内核和离开内核时,寄存器(包括通用寄存器和程序计数器)分别被保存和恢复。
当一个进程在 CPU 上运行时,这就意味着操作系统没有运行。既然操作系统没有运行,那它怎么能做事情?
过去某些系统采用的一种被称为**协作(cooperative)**的方式,在协作调度系统中,OS 通过等待系统调用,或某种非法操作发生,从而重新获得 CPU 的控制权。但是当进程陷入无限循环时,唯一的解决办法就是重新启动计算机。
如何在没有协作的情况下获得 CPU 的控制权呢?
答案很简单:时钟中断(timer interrupt)。
时钟设备可以编程为每隔几毫秒产生一次中断。产生中断时,当前正在运行的进程停止,操作系统中预先配置的中断处理程序(interrupt handler)会运行。此时,操作系统重新获得 CPU 的控制权。
至于中断发生后,OS 是决定切换下一个进程,还是继续执行原先的进程?
那就要看操作系统采用的调度策略了,大家可以关注我的下一篇博客。