CPU虚拟化
- 什么是虚拟化?
物理概念上不存在,但逻辑概念上是存在的。
比如:宾馆的房间,当你使用的时候,别人是无法使用的,在这段时间内,它是独属于你,同理,在其它用户使用期间,它是独属于其它用户的。换句话说,宾馆在物理意义上只有一间,在每个用户使用期间,它都是独属于每个用户,就好像每个人都拥有一间房间一样,即:逻辑上存在很多间房间
- 为什么需要虚拟化?
计算机的各种资源有限,但是实际情况下,用户往往希望计算机能“同时”运行多个程序。
- 如何实现虚拟化?
- 时分复用——分时复用
为每个程序建立至少一个进程,让所有进程进行并发执行。
即:操作系统把CPU时间划分为多个均等的时间片。例如:每5ms一个时间片,在每个时间片内运行一个进程。当进程的时间片用完被切换后,过一段时间会重新接着运行。
- 空分复用
由于计算机的内存资源有限,操作系统会惰性执行进程,即:仅在程序执行期间需要加载的代码或数据片段才会被加载,运行完毕后,操作系统会将该部分换出,再重新加载另外一部分。
进程
- 什么是进程?
- 进程是程序的一次执行
- 进程是一个程序及其数据在处理机上顺序执行时所发生的活动
- 进程是具有独立功能的程序在一个数据集合上运行的过程,它是系统进行资源分配和调度的一个独立单位
- 进程的组成
- 进程控制块(Process Control Block,PCB):存储进程的调度信息、控制信息、处理机状态等,位于操作系统内核(kernel)中,受到保护,无法查看。
- 程序段
- 相关的数据段
- 程序如何转化为进程
- 将代码和静态数据加载(load)到内存
- 为程序的运行时栈(run-time stack)分配一些内存用于存放局部变量、函数参数和返回地址
- 可能会为程序的堆分配一些内存。在C程序中,堆用于显示请求的动态分配数据。如:通过malloc()或者realloc()请求空间,并通过free()释放空间
- 执行一些其他初始化任务,特别是和输入/输出相关的任务
- 进程的状态
运行(running):进程获得CPU,程序正在执行的状态
就绪(ready):进程已处于准备号运行的状态,即:进程已分配到除CPU以外的所有必要资源后,只需要再获得CPU,便可立即执行
阻塞(blocked):正在执行的进程由于发生某事件(如I/O请求,申请缓冲器失败等)暂时无法继续执行的状态,即:进程的执行收到阻塞
创建状态:系统没有足够的内存让内存装入其中,进程的创建工作没有完成,进程无法被调度执行
终止状态:系统可以处于已退出但尚未清理(将PCB清0,并将PCB空间返还系统)的状态
- 进程是受限直接执行的
- 什么是受限直接执行?
“直接执行”:只需要在CPU上运行
“受限”:进程的操作收到操作系统的限制,比如:向磁盘发出I/O请求或者获得更多的系统资源(比如:CPU或者内存)
- 受限直接执行的原因?
“直接执行”:为了让程序尽可能快的执行
“受限”:避免进程执行一些危险的操作
如何实现受限直接执行
- 实现“受限”
(1)用户模式(user mode):用户模式下,运行的代码会受到限制。比如:在用户模式下运行,进程不能发出I/O请求。
(2)内核模式(kernel mode):和用户模式相对,操作系统(或内核)都是在这种模式下运行
(3)系统调用:用户希望执行某种特权操作(比如:从硬盘读取数据),硬件为用户程序提供了执行系统调用的能力,允许内核小心地向用户程序暴露某些关键功能,例如:访问文件系统,创建和销毁进程、和其它进程通信,以及分配更多的内存)
(4)陷阱(trap)指令:要执行系统调用就必须执行陷阱指令,该指令在被操作系统加载到内核的同时将用户模式提升为内核模式。完成后,操作系统会调用一个从陷阱返回指令(return-from-trap),回到用户模式
(5)陷阱表(trap table):计算机启动时,操作系统就会初始化陷阱表,并且CPU会记住它的位置。当执行陷阱指令时,CPU就会根据陷阱表找到需要运行的指令。
- 实现“受限”
- 实现直接执行——实现进程的切换
(1)操作系统获取CPU的控制权
a. 协作方式(等待系统调用):操作系统等待进程进行系统调用或者某种非法操作发生时,从而获得CPU控制权
b. 非协作方式(操作系统进行控制):通过时钟中断(timer interrupt),时钟设备可以每隔几秒钟产生一次中断,产生中断时,正在运行的程序停止,操作系统中预先配置的中断处理程序(iterrput handler)会运行,此时操作系统会重新获得CPU控制权
(2)保存和恢复上下文
a. 调度程序(scheduler):决定继续运行当前正在运行的程序还是切换到另一个进程
b. 上下文切换:为当前正在运行的进程保存一些信息,并为即将执行的进程恢复一些信息(借助PCB实现)
c. 进行上下文切换时,操作系统会执行一些底层汇编代码,来保存通用寄存器(GR)、程序计数器(PC),以及当前正在运行进程的内核栈指针,然后恢复寄存器、程序计数器,并切换内核栈,供即将运行的进程使用。
- 系统调用期间发生时钟中断怎么办?
- 处理一个中断时发生另外一个中断怎么办?
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。