# 操作系统

普渡大学的 Gene Spafford 曾对我说，操作系统“是为了提供更方便的抽象。其中一位前教授 Phil Enslow 曾将操作系统定义为支持计算资源受控共享的机制、策略和程序。”这是个很好的观点，因为它涵盖了安全策略、调度策略等内容，这些通常不被视为用户与硬件之间接口的一部分，也不被看作是应用程序执行环境的一部分。

操作系统为用户提供了便利，同时提高了硬件使用效率。可将其比作政府，虽然自身没有直接的实用功能，但为其他程序提供了能够运行的环境。

操作系统是资源分配者，同时也是控制程序，防止错误和不当使用，调节计算机及输入/输出（I/O）设备的运行。

最初（直到约 1954 年）只有硬件（Wilkes 的学生 Stan Kelly-Bootle 告诉我：“我有不同的看法，但常有人称 Swinnerton-Dwyer 于 1953/1954 年开发的 EDSAC Monitor 是第一款真正的操作系统”）。早期占据庞大空间的计算机由控制台操作，程序员在控制台编写程序，然后手动将程序加载到内存中：起初通过前面板上的开关一次输入一条指令，后来通过打孔卡和纸带输入指令。程序员通过观察控制台上闪烁的指示灯来监控执行、发现错误或检查内存和寄存器的内容。输出则直接打印或打孔卡、纸带保存以供后续打印。这种方式真正实现了“动手操作”和“交互式”。

随着硬件越来越多——卡片读取器、行式打印机、磁带设备——以及越来越多的软件——常用函数库的开发——问题开始出现（常用函数可以被复制到新程序中，无需重写。最初，程序是打孔纸带，按顺序一个一个的加载到机器中，或者实际上按顺序拼接起来）。

每个 I/O 设备都有其特殊性。必须为每个设备编写特殊的子程序，即设备驱动程序，这些设备有特定的缓冲区、标志、寄存器和特殊位。

还有编译器。编译器用于在高级语言和机器语言之间进行翻译。第一款完整的编译器由格蕾丝·赫柏和她在雷明顿兰德公司的团队于 1952 年设计。后来，FORTRAN、COBOL 等语言的编译器被开发出来。这使得程序员的工作更容易，但软件也变得更复杂。

FORTRAN 就是个很好的例子。为了准备 FORTRAN 程序，操作员会将 FORTRAN 编译器加载到计算机中，这需要将相应的磁带安装到磁带驱动器上。程序（已输入打孔卡）随后由读卡器读取，并写入另一盘磁带。FORTRAN 编译器的输出（汇编语言）需要组装，这又要求安装汇编器磁带。汇编器会链接适当的库例程，最终生成可执行的二进制程序。程序可以从控制台加载和调试，但通常并不会这样做。

在整个作业准备过程中，CPU 都处于空闲状态。装载磁带时，CPU 也空闲。为提高效率，作业被批量处理：按 FORTRAN 作业一组，COBOL 作业一组，等等。

但问题仍然很多。

计算机的时间太宝贵，不能浪费。

离线处理是第一个解决方案，作业先被批量存储在磁带上，然后再将磁带装入计算机。通过在不同机器上执行，CPU 和 I/O 操作可以复用时间。那么，为什么不在同一台机器上实现这种复用呢？于是，缓冲（临时存储数据以弥补不同设备速度差异）和假脱机（将慢速设备与主进程解耦）应运而生。假脱机使 CPU 和 I/O 能以更高速度运行，同时也使作业池的形成成为可能，从而带来了作业调度。

作业调度中最重要的元素是多道程序设计。多道程序设计对于计算机来说，就像我们大多数人在现实中做的事情一样：在等待另一个任务的某个环节完成时，执行一个任务——比如等水开时做烤面包。20 世纪 50 年代后期，这意味着“中断”。外围设备由中央处理器（CPU）启动，并自动继续执行其任务。当任务完成或设备需要处理时，该设备会向 CPU 发送中断，迫使 CPU 关注该设备。

道格拉斯·麦克罗伊指出，“出现了一个有趣的倒退。当 IBM 704 进入麻省理工学院时，曾经在 Whirlwind 上成为常态的自动操作反而消失了。”

多道程序设计的逻辑延伸是多任务处理，或者说分时系统。为此，我们去看看麻省理工学院的情况。
