机制:受限直接执行
时分共享CPU
简单说来,就是运行一个进程一段时间,然后运行另一个进程,让它们看起来像同时进行。
关键问题:如何高效又可控地虚拟化CPU?
受限直接运行
“直接运行”:直接在CPU运行程序。
过程:OS在进程列表中创建一个进程条目,为其分配内存,将程序代码从磁盘加载到内存中,找到入口点(main()函数或类似的),跳转并运行。
问题一:操作系统如何保证程序不逾矩并高效运行?
答:受限制的操作
硬件会提供不同的执行模式来协助操作系统,用户模式(user mode)和内核模式(kernel mode)
据常识易知,用户模式下一些操作会受限制,比如进程无法发出I/O请求。
新问题:在用户模式下希望执行某种特殊操作怎么办
程序可以执行特殊的陷阱(trap)命令,顾名思义,跳入内核并将级别提升。完成后,OS调用一个特殊的从陷阱返回的指令(return-from-trap),回到用户模式。
陷阱如何知道在OS内运行哪些代码?
内核通过在启动时设置陷阱表(trap table)来实现。
补充:系统调用 VS 过程调用
系统调用是过程调用,只不过隐藏在过程调用内部的是陷阱指令。库使用与内核一致的调用约定将参数,系统调用号(栈或特定寄存器中)放入特定位置。
问题二:如何在进程中切换?
协作方式:等待系统调用
这是早期OS采用的一种方式,即相信程序会合理运行。或某种非法操作发生,OS重新获得CPU的控制权。
非协作方式:操作系统进行控制
利用时钟中断(几毫秒产生一次中断,当前运行程序会停止)使OS重新获得CPU的使用权。
上下文切换
当OS决定切换程序运行时,就会执行上下文切换。即为当前正在执行的进程保存一些寄存器的值(到内核栈),并为即将执行的进程恢复一些寄存器的值。
注意此图中有两种寄存器的保存/恢复。
由硬件隐式保存在内核栈;
被OS显示保存在进程结构的内存中,这一操作让系统好像刚由A陷入内核变为好像刚由B陷入内核。