1. 底层机制
操作采用时分共享CPU的方式实现虚拟化CPU。在实现虚拟化的同时,我们要保证整体性能且不失去CPU的控制权。
1.1 用户模式与内核模式
为了防止某个任务抢夺所有资源或者影响其它任务的运行,我们需要限制进程的操作,保证操作系统的控制权。
在用户模式下,应用程序不能完全访问硬件资源。在内核模式下,操作系统可以访问机器的全部资源。并提供了内核态与用户态的切换方式(陷阱指令也叫系统调用)。
1.1.1 系统调用
操作系统启动的第一件事,就是告诉硬件在发生某些异常时要运行哪些代码。每个都有一个内核栈,在进入内核和离开内核是,寄存器被保存和恢复。
1.1.2 用户态与内核态切换过程
内核态 | 硬件 | 用户态 |
---|---|---|
系统启动初始化陷阱表 | ||
记录系统调用处理程序的地址 | ||
系统运行,创建进程、分配内存、加载程序代码段、设置程序栈、用寄存器/程序计数器填充内核栈、从陷阱返回 | ||
从内核恢复寄存器、转向用户态,跳到main函数地址 | ||
运行main函数直到调用系统调用,陷入操作系统 | ||
将寄存器保存到内核栈、进入内核态,跳到陷阱处理函数地址 | ||
处理陷阱、做系统调用的工作、从陷阱返回 | ||
从内核恢复寄存器、转向用户态,跳到陷阱之后的程序计数器 | ||
…从main返回,陷入(通过exit() | ||
释放进程内存、停止进程 |
1.2 进程间切换
1.2.1 协作方式:等待系统调用
过去某些操作系统采用过这种方式,在这种模式下,操作系统相信进程会合理运行。运行过长的进程会主动放弃CPU,以便其他进程使用。
操作系统等待进程进行系统调用或者某些非法操作,从而重新控制CPU。这种方式比较被动,某些恶意程序可能进入无限循环,其他进程得不到运行机会。
1.2.2 非协作方式:操作系统控制
操作系统通过时间中断,运行预设的中断处理程序,重新获取CPU控制权。因此可以停止当前进程,并启动另一进程。在这个过程中,各种寄存器会被保存,当切换回原进程时,进程状态能得到恢复。
1.2.3 保存和恢复上下文
如何决定进行切换,OS会执行一些底层代码,即所谓的上下文切换。上下文切换在概念上很简单:操作系统要做的就是为当前正在运行的进程保存一些寄存器的值到它的内核栈,并为即将运行的进程恢复一些寄存器的值。这样操作系统可以确保操作系统从陷阱返回指令时,即将执行的进程变成了正在执行的进程。至此上下文切换完成。