第13章 操作系统设计

在过去的12章中,我们讨论了许多话题并且分析了许多与操作系统相关的概念和实例。但是研究现有的操作系统不同于设计一个新的操作系统。在本章中,我们将简述操作系统设计人员在设计与实现一个新系统时必须要考虑的某些问题和权衡。

在系统设计方面,关于什么是好,什么是坏,存在着一定数量的民间传说在操作系统界流传,但是令人吃惊的是这些民间传说很少被记录下来。最重要的一本书可能是Fred Brooks的经典著作The Mythical Man Month(中文译名《人月神话》)。在这本书中,作者讲述了他在设计与实现IBM OS/360系统时的经历。该书的20周年纪念版修订了某些素材并且新增加了4章(Brooks,1995)。

有关操作系统设计的三篇经典论文是“Hints for Computer System Design”(计算机系统设计的忠告,Lampson,1984)、“On Building Systems that Will Fail”(论建造将要失败的系统,Corbató,1991)和“End-to-End Arguments in System Design”(系统设计中端到端的论据,Saltzer等人,1984)。与Brooks的著作一样,这三篇论文都极其出色地经历了岁月的考验,其中的大多数真知灼见在今天仍然像文章首次发表时一样有效。

广告:个人专属 VPN,独立 IP,无限流量,多机房切换,还可以屏蔽广告和恶意软件,每月最低仅 5 美元

本章吸收了这些资料来源,另外加上了作者作为三个系统的设计者或合作设计者的个人经历,这三个系统是:Amoeba(Tanenbaum等人,1990)、MINIX(Tanenbaum和Woodhull,1997)和Globe(Van Steen等人,1999a)。由于操作系统设计人员在设计操作系统的最优方法上没有达成共识,因此与前面各章相比,本章更加主观,也无疑更具有争议。

13.1 设计问题的本质

操作系统设计与其说是精确的科学,不如说是一个工程项目。设置清晰的目标并且满足这些目标非常困难。我们将从这些观点开始讨论。

13.1.1 目标

为了设计一个成功的操作系统,设计人员对于需要什么必须有清晰的思路。缺乏目标将使随后的决策非常难于做出。为了明确这一点,看一看两种程序设计语言PL/I和C会有所启发。PL/I是IBM公司在20世纪60年代设计的,因为在当时必须支持FORTRAN和COBOL是一件令人讨厌的事,同时令人尴尬的是,学术界背地里嚷嚷着Algol比这两种语言都要好。所以IBM设立了一个委员会来创作一种语言,该语言力图满足所有人的需要,这种语言就是PL/1。它具有一些FORTRAN的特点、一些COBOL的特点和一些Algol的特点。但是该语言失败了,因为它缺乏统一的洞察力。它只是彼此互相竞争的功能特性的大杂烩,并且过于笨重而不能有效地编译。

现在考察C语言。它是一个人(Dennis Ritchie)为了一个目的(系统程序设计)而设计的。C语言在所有的方面都取得了巨大的成功,因为Ritchie知道他需要什么,不需要什么。结果,在面世几十年之后,C语言仍然在广泛使用。对于需要什么要有一个清晰的洞察力是至关重要的。

操作系统设计人员需要什么?很明显,不同的系统会有所不同,嵌入式系统就不同于服务器系统。然而,对于通用的操作系统而言,需要留心4个基本的要素:

1)定义抽象概念。

2)提供基本操作。

3)确保隔离。

4)管理硬件。

下面将描述这些要素。

一个操作系统最重要但可能最困难的任务是定义正确的抽象概念。有一些抽象概念,例如进程和文件,多年以前就已经提出来了,似乎比较显而易见。其他一些抽象概念,例如线程,还比较新鲜,就不那么成熟了。例如,如果一个多线程的进程有一个线程由于等待键盘输入而阻塞,那么由这个进程通过调用fork函数创建的新进程是否也包含一个等待键盘输入的线程?其他的抽象概念涉及同步、信号、内存模型、I/O的建模以及其他领域。

每一个抽象概念可以采用具体数据结构的形式实例化。用户可以创建进程、文件、信号量等。基本操作则处理这些数据结构。例如,用户可以读写文件。基本操作以系统调用的形式实现。从用户的观点来看,操作系统的核心是由抽象概念和其上的基本操作所构成的,而基本操作则可通过系统调用加以利用。

由于多个用户可以同时登录到一台计算机,操作系统需要提供机制将他们隔离。一个用户不可以干扰另一个用户。为了保护的目的,进程概念广泛地用于将资源集合在一起。文件和其他数据结构一般也是受保护的。确保每个用户只能在授权的数据上执行授权的操作是系统设计的关键目标。然而,用户还希望共享数据和资源,因此隔离必须是选择性的并且要在用户的控制之下。这就使问题更加复杂化了。电子邮件程序不应该弄坏Web浏览器程序,即使只有一个用户,不同的进程也应该隔离开来。

与这一要点密切相关的是需要隔离故障。如果系统的某一部分崩溃(最为一般的是一个用户进程崩溃),不应该使系统的其余部分随之崩溃。系统设计应该确保系统的不同部分良好地相互隔离。从理想的角度看,操作系统的各部分也应该相互隔离,以便使故障独立。

最后,操作系统必须管理硬件。特别地,它必须处理所有低级芯片,例如中断控制器和总线控制器。它还必须提供一个框架,从而使设备驱动程序得以管理更大规模的I/O设备,例如磁盘、打印机和显示器。