提高系统的性能和效率是操作系统的核心目标之一,本章展现了操作系统在性能上的一系列功能改进:
- 通过提前加载应用程序到内存,减少应用程序切换开销
- 通过协作机制支持程序主动放弃处理器,提高系统执行效率
- 通过抢占机制支持程序被动放弃处理器,提高不同程序对处理器资源使用的公平性,也进一步提高了应用对 I/O 事件的响应效率
上一个 Lab,我们实现了一个批处理操作系统。首先,它能够自动按照顺序加载并运行序列中的每一个应用,当一个应用运行结束之后无需操作员的手动替换;另一方面,在硬件级特权隔离机制的帮助下,运行在更高特权级的操作系统不会受到有意或者无意出错的应用的影响;在硬件异常触发机制的帮助下,可以全方位监控运行在用户态低特权级的应用执行,一旦应用越过了特权级界限或主动申请获得操作系统的服务,就会触发 Trap 并进入到批处理系统中进行处理。无论原因是应用出错或是应用声明自己执行完毕,批处理系统都只需要加载应用序列中的下一个应用并让其执行。可以看到批处理系统的特性是:在内存中同一时间最多只需驻留一个应用。这是因为只有当一个应用出错或退出之后,批处理系统才会去将另一个应用加载到相同的一块内存区域。
而计算机硬件在快速发展,内存容量在逐渐增大,处理器的速度也在增加,外设 I/O 性能方面的进展不大。这就使得以往内存只能放下一个程序的情况得到很大改善,但处理器的空闲程度加大了。于是科学家就开始考虑在内存中尽量同时驻留多个应用,这样处理器的利用率就会提高。但只有一个程序执行完毕后或主动放弃执行,处理器才能执行另外一个程序。我们把这种运行方式称为 多道程序(Multiprogramming) 。
早期的计算机系统大部分是单处理器计算机系统,由于计算机系统很昂贵,所以是多人共用一台计算机。当处理器进一步发展后,它与 I/O 的速度差距也进一步拉大。这时计算机科学家发现,在 多道程序 运行方式下,一个程序如果不让出处理器,其他程序是无法执行的。如果一个应用由于 I/O 操作让处理器空闲下来或让处理器忙等,那其他需要处理器资源进行计算的应用还是没法使用空闲的处理器资源。于是就想到,让应用在执行 I/O 操作或空闲时,可以主动 释放处理器 ,让其他应用继续执行。当然执行 放弃处理器 的操作算是一种对处理器资源的直接管理,所以应用程序可以发出这样的系统调用,让操作系统来具体完成。这样的操作系统就是支持 多道程序 或 协作式多任务 的协作式操作系统。
本 Lab 主要是设计和实现建立支持 多道程序 的初级操作系统、支持 多道程序 的协作式操作系统,从而对可支持运行一批应用程序的多种执行环境有一个全面和深入的理解,并可归纳抽象出 任务 、 任务切换 等操作系统的概念。
在课程仓库的 code/lab4
目录下:
$ cd os
# 构建并运行代码 (Makefile 中已包含了 user 目录下的 make build 命令)
$ make run -j $(nproc)
...
[kernel] Hello, world!
AAAAAAAAAA [1/5]
BBBBBBBBBB [1/2]
CCCCCCCCCC [1/3]
AAAAAAAAAA [2/5]
BBBBBBBBBB [2/2]
CCCCCCCCCC [2/3]
AAAAAAAAAA [3/5]
Test write_b OK!
[kernel] Application exited with code 0
CCCCCCCCCC [3/3]
AAAAAAAAAA [4/5]
Test write_c OK!
[kernel] Application exited with code 0
AAAAAAAAAA [5/5]
Test write_a OK!
[kernel] Application exited with code 0
All applications completed!
从运行结果中我们可以看到,多道程序的应用分别会输出一个不同的字母矩阵。当他们交替执行的时候,我们将看到字母行的交错输出。