2.3 操作系统基础

操作系统是计算机硬件和用户(程序和人)的接口,它使得其他程序更加方便、有效地执行,并能方便地对计算机硬件和软件资源进行访问。

操作系统的两个主要设计目标是:更有效地使用硬件;更容易地使用资源。

操作系统是非常复杂的系统,因此很难给予它一个普遍认同的定义。我们在这里列举一些通用的定义。

● 操作系统是介于计算机硬件和用户(程序或人)之间的接口。

● 操作系统是一种使得其他程序更加方便、有效执行的程序(或一组程序)。

● 操作系统作为通用管理程序管理着计算机系统中每个部件的活动,并确保计算机系统中的硬件和软件资源能够更加有效地使用。当资源使用出现冲突时,操作系统应能够及时处理、排除冲突。

2.3.1 操作系统的发展及其意义

自1946年2月14日世界上第一台电子计算机“埃尼阿克”(ENIAC)在美国宾夕法尼亚州立大学诞生以来,计算机技术的发展以惊人速度向前推进着。以计算机技术为核心的信息技术领域发生了翻天覆地的变化。

回首当年,“埃尼阿克”揭开了电子计算机发展和应用的序幕,宣告了一个时代的开始。从规模上看,“埃尼阿克”是个“笨重”的家伙,因为它长30.48m、宽1m、占地面积为170m2、重达30 t、拥有30个操作台、相当于10 间普通房间的大小,所以称得上是地地道道的庞然大物,计算机专家操作“埃尼阿克”的图片如图2.13所示。

图2.13 计算机专家在操作“埃尼阿克”

说“埃尼阿克”笨,是因为它的智能太低,只有专家才会使用,普通用户只能望而却步。究其原因,就是它缺乏操作系统。

今天,计算机已经可以做得非常轻巧,并且早已进入寻常百姓家。“轻”,当然是硬件发展的卓越成果。“巧”,则得益于装备了功能丰富的操作系统。操作系统带来的易操作性使很多用户甚至根本意识不到自己其实是在使用计算机。试想,有多少用户在使用智能手机时会想到自己实际上是在操作一台功能比“埃尼阿克”提高了成千上万倍的计算机呢?

不只是“埃尼阿克”,早期的计算机都没有操作系统。在没有操作系统的年代,使用计算机并不是一件容易的事情。

起初,计算机用户只能通过操作一排排的机械开关,把程序一位一位地输入到计算机中。逐渐地,出现了机器语言,用户可以把用机器语言编写的程序以打孔的形式记录在穿孔卡或纸带上,让计算机从穿孔卡或纸带上读取程序。可见,仅是把程序输入到计算机中就是一件烦琐的工作。

同样,从计算机中获取输出结果也并不轻松。为了减轻用户使用计算机时的输入/输出负担,人们为计算机设计了输入/输出控制系统(IOCS,Input-Output Control System)。该系统的实现也许可以算得上是今天操作系统思想的开端。的确,计算机的人机交互功能在计算机的普及和应用中起到了重要的推动作用。今天,我们不但可以借助键盘、鼠标和显示器来操作计算机,还可以通过手写输入甚至语音输入与计算机进行对话。

在使用早期计算机时,用户遇到的另一个问题是,每次只能由一个用户独占整台计算机,并且只能让计算机做一件事情。如果有多个用户想使用计算机,或者一个用户想同时执行多个程序,则只能通过排队解决,即当一个程序运行结束之后,再开始执行另一个程序。

为了解决这一问题,人们为计算机设计了批处理功能,使得用户可以一次向计算机提交多个任务,让计算机自动地一个接一个地把整批任务执行完。20 世纪50年代中期,在美国通用汽车研究实验室诞生了世界上第一个操作系统。那是一个为IBM 701主机配备的批处理操作系统。当时人们似乎并没有考虑给它起一个名字。

批处理操作系统在一定程度上提高了计算机的使用效率,但并没有让用户实现同时执行多个程序的愿望。1962年,美国麻省理工学院的考巴脱(F.J. Corbató)、达格特(M.M.Daggett)和戴利(R.C. Daley)发表了有关分时操作系统的研究论文。在美国麻省理工学院(MIT)计算中心诞生了世界上第一个兼容分时操作系统(CTSS)。

显而易见,有了分时操作系统的支持,多个用户能够同时使用一台计算机,因此计算机资源的利用率得到了进一步的提高。

至此,不妨从感性的角度谈一谈操作系统概念的基本意义。什么是操作系统呢?操作系统就是能够帮助用户方便地操作计算机,并能够提高计算机资源利用率的软件系统。作者认为,之所以称为“操作系统”,原因在于它是为方便用户高效地操作计算机而设计的。

20 世纪60年代末期,在CTSS的基础上,美国的麻省理工学院、贝尔实验室和通用电气公司联合开发出了称为多路信息和计算系统(Multics)的操作系统。在Multics的影响下,贝尔实验室的汤普森(K.Thompson)和里奇(D. Ritchie)在20世纪70年代初期开发出了UNIX操作系统,并因此获得了1983年图灵奖。曾领导兼容分时系统和Multics开发的美国麻省理工学院的考巴脱教授在1990年也获得了图灵奖。

1973年,基尔代尔(G.A. Kildall)为Intel 8008芯片开发了8位CP/M操作系统。这是基于英特尔芯片的计算机上的第一个操作系统。1980年4月,美国西雅图计算机产品公司的帕特森(T. Paterson)开发出QDOS操作系统,是CP/M的16位克隆版。1981年7月,微软公司购买了QDOS,随后以PC DOS和MS DOS的形象广泛应用于IBM的个人计算机中。在MS DOS的基础上,微软公司于1985年开发出了Windows 1.0版本,从此点燃了Windows操作系统的燎原之火。

在过去几十年,成百上千的操作系统涌现出来,UNIX操作系统和Windows操作系统可以说是其中最具代表性的两大主要流派,在操作系统领域的贡献举足轻重。

微型化是计算机得以走进千家万户的重要因素之一。同时,在与微型化相对的方向上,高性能计算也是现代计算机技术追求的一个重要目标。在与分时处理相对的方向上,实时处理同样是一项重要的(某种意义上甚至是更重要的)应用需求。

操作系统在硬件技术和应用需求的驱动下不断向前发展。各类计算机都需要有与之相适应的操作系统为其提供支持。我们不但能看到支持桌面应用的Windows XP和Linux等操作系统,或者支持移动便携式应用的Linux DA O/S、Palm OS和Windows CE等操作系统,也能看到支持超级计算应用的UNICOS等操作系统;不但能看到支持分时应用的UNIX等操作系统,也能看到支持实时应用的QNX等操作系统。

计算机技术及其应用需求的多样性,造成了操作系统领域技术和产品的丰富多彩。而无论信息技术世界如何纷繁多变,为计算机系统提供基础支撑始终是操作系统永恒的主题。故此,纵然信息技术经历了几十年的沧海桑田,操作系统却一直是其华美乐章中多彩的主旋律。

2.3.2 操作系统的演化

操作系统已经经历了很长的一段发展历程,2.3.1节已把操作系统的发展概况呈现给了大家,下面简要地归纳一下操作系统在发展过程中演化形成的主要类型。

1.批处理操作系统

批处理操作系统设计于20世纪50年代,目的是控制大型计算机。当时计算机十分庞大。它们用穿孔卡片输入数据,用行式打印机输出结果,磁带设备作为辅助存储介质。

每个执行的程序叫做作业。想要执行作业的程序员通过穿孔卡片将程序和数据输入计算机,并向操作室发出请求。程序员对系统没有控制和交互。穿孔卡片由操作员处理。如果程序运行成功,结果将传给程序员,如果不成功,则报错。

2.分时操作系统

为了有效使用计算机资源,引入了多道程序。它的做法是可以将多个作业装入存储器,并且仅当资源可用时分配给需要它的作业。例如,当一个程序正使用输入/输出设备时,CPU则处于空闲状态,并可以供其他程序使用。

多道程序带来了分时的概念:资源可以被不同的作业共享。每个作业可以分到一段时间来使用资源。因为计算机运行速度远远快于人的反应,所以分时系统对于用户是透明的,每个用户都感觉整个系统在为自己服务。

最终,利用分时技术的多道程序极大地提高了计算机系统的使用效率。但是,仍需要更加复杂的操作系统,它必须可以调度:给不同的程序分配资源并决定哪一个程序什么时候使用哪一种资源。

在这个时期,用户和计算机的关系也改变了。用户可以直接操作系统本身而不必通过操作员。一个新的术语也随之产生:进程。作业是要运行的程序,进程则是在存储器中等待资源的程序。

3.个人操作系统

当个人计算机产生后,需要有一类适合这类计算机的操作系统。于是,单用户操作系统,如DOS(磁盘操作系统)产生了。

4.并行系统

对更快速度和更有效的要求导致了并行系统的设计:在同一计算机中安装了多个CPU,每个CPU可以处理一个程序或程序的一部分。这意味着很多任务可以并行地处理而不再是串行处理。当然,这种操作系统要比单CPU的操作系统复杂得多。

5.分布式系统

网络化和交互式网络化的发展扩大了操作系统的内涵,产生了一种新的操作系统。以往必须在一台计算机上运行的作业现在可以由远隔千里的多台计算机共同完成。程序可以在一台计算机上运行一部分而在另一台计算机上运行另一部分,只要它们通过交互式网络如互联网互连。此外,资源可以是分布式的,程序需要的文件可能分布在世界的不同地方。分布式系统结合了以往系统的特点和新功能,如安全控制。

2.3.3 操作系统的构成

现在的操作系统十分复杂,它需要管理计算机系统内不同的资源。它像是一个有多个顶层经理的管理机构,每个经理负责自己部门的管理,并且相互协调合作。现代操作系统至少具有以下4 种职能:存储管理、进程管理、设备管理、文件管理。就像很多组织有不直接在某个部门经理管理之下的部门一样,操作系统也有这样的部分,称为用户界面或命令解释程序,它负责操作系统与外界的联系(类似于公共关系部门)。

1.内存管理器

现在计算机操作系统的一个重要职责是存储管理。近年来,计算机的存储容量激增,同样,所处理的数据和程序也越来越大。存储分配必须进行管理以避免“内存不足”的错误。操作系统按照存储管理可以分为两大类:单道程序和多道程序。

1)单道程序

单道程序在过去很流行,但是它还是值得一提,因为它有助于理解多道程序。在单道程序里,大多数内存专用于单一的程序,仅有一小部分用来装载操作系统。在这种配置下,程序整体装入内存运行,运行结束后由其他程序取代。

2)多道程序

在多道程序中,同一时刻可以装入多个程序并且能够同时执行这些程序。CPU轮流为它们服务。

从20世纪60年代开始,多道程序已经经过了一系列改进。有两种技术属于非交换类,这意味着程序在运行期间始终驻留在内存中。另外两种技术属于交换技术类。也就是说,在运行过程中,程序可以在内存和硬盘之间多次交换。

a. 分区调度

多道程序使用的第一种技术称为分区调度。在这种模式中,内存被分为不定长的几个分区。每个部分或分区保存一个程序。CPU在各个程序之间交替服务。它由一个程序开始,执行一些指令直到有输入/输出操作或分配给那个程序的时限到达。CPU保存最近执行指令的内存地址,然后转入下一个程序。对下一个程序采用同样的步骤执行。当为所有程序服务完毕后,CPU再转回第一个程序。当然,CPU可以进行优先级存取。

在这种技术下,每个程序完全载入内存,并占用了连续的地址。分区调度提高了CPU的使用效率,但仍有一些问题。

b. 分页调度

分页调度提高了分区调度的效率。在分页调度下,内存被分成大小相等的若干个部分,称之为帧;程序也被分为大小相等的部分,称之为页。页和帧的大小通常是一样的,并且与系统用于从存储设备中提取信息的块大小相等。

页被载入到内存的帧中。如果程序有3页,它就在内存中占用3个帧。在这种技术下,程序在内存中不必是连续的。两个连续的页可以占用内存里不连续的两个帧。分页调度对于分区调度的优势在于:一个需要6个帧的程序可以代替两个各占有不连续的3个帧的程序。新程序不必等到有6个连续的帧出现后再载入内存。

分页调度在一定程度上提高了效率,但整个程序仍需要在运行前全部载入内存。这意味着如果只有4个不连续帧,一个需要6个帧的程序是不能载入内存的。

c. 请求分页调度

分页调度不要求把程序装载在连续的内存中,但仍要求把程序整体载入内存中执行。请求分页调度去掉了后一种限制。在请求分页调度中,程序被分成页,但是页可以依次载入内存、运行,然后被另一个页代替。也就是说,内存可以同时载入多个程序的页。此外,来自同一个程序的连续页可以不必载入同一个帧,页可以被载入任何一个空闲帧。

3)虚拟内存

请求分页调度和请求分段调度意味着当程序执行时,一部分程序驻留在内存中,一部分则放在硬盘上。这就意味着,例如,10MB内存可以运行10个程序。每个程序3MB,一共30MB,任一时候10个程序中的10MB在内存中,还有20MB在硬盘上。这里实际上只有10MB内存但却有30MB的虚拟内存。

2.进程管理器

操作系统的第二个功能是进程管理。

1)程序、作业和进程

现代操作系统关于指令集有三个术语:程序、作业和进程。尽管这些术语比较模糊,并且不同的操作系统对于它们的定义并不一致,我们还是可以非正式地定义这些术语。

● 程序。程序是由程序员编写的一组稳定的指令,存储在硬盘(或磁盘)上,它可能会也可能不会成为作业。

● 作业。从程序被选中执行到其运行结束并再次成为程序的这段过程中,程序称为作业。整个过程中,作业可能会或不会被执行。它或者驻留在硬盘上等待被装入内存,或者在内存中等待被CPU执行,或者驻留在硬盘或内存中等待输入/输出事件,或者在CPU执行时在内存中等待。在所有这些情况下的程序才称为作业。当作业执行完毕(正常或不正常),作业又变成程序并再次驻留在硬盘中,操作系统不再管理程序。需要注意的是:每个作业都是程序,但并不是所有的程序都是作业。

● 进程。进程是执行中的程序。该程序开始运行但还未结束。换句话说,进程是驻留在内存中的作业,它是从众多等待作业中选取出来并装入内存中的作业。进程可以处于运行状态或等待CPU调用。只要作业被装入内存就成为进程。需要注意的是:每个进程都是作业,而未必每个作业都是进程。

2)状态图

明白了程序怎样变成作业及作业怎样变成进程时,程序、作业、进程的关系也就很明显了。状态图显示了每个实体的不同状态。

当程序被操作系统选中时就成为作业并且成为保持状态。直至它被载入内存之前都保持这个状态。当内存可以整体或部分地载入这个程序时,作业转成就绪状态,并变成进程。它在内存中保持这个状态直至CPU执行它;这时它转成运行状态。当处于运行状态后,可能出现下面三种情况之一:① 进程运行直至它需要输入/输出;② 进程可能耗尽所分配的时间片;③ 进程终止。

在第一种情况下,进程进入等待状态并且等待直至输入/输出结束。在第二种情况下,直接进入就绪状态。在第三种情况下,它进入终止状态,并且不再是进程。进程进入终止状态前在运行、等待、就绪状态中转换多次。注意:如果系统使用虚拟内存,并且在内存中将程序交换出或入,状态图可能更加复杂。

3)调度器

将作业或进程从一个状态转到另一个状态,进程管理器使用了两个调度器:作业调度器和进程调度器。

(1)作业调度器。作业调度器将作业从保持状态转入就绪状态,或者从运行状态转入终止状态。换句话说,作业调度器负责从作业中创建进程并终止进程。

(2)进程调度器。进程调度器将进程从一个状态转入另一个状态。当进程等待某事件发生时,它使这一进程从运行状态进入等待状态。当给进程分配的时间片用完时,这个进程从运行状态进入就绪状态。当触发事件发生时,进程将从等待状态进入就绪状态。当CPU准备运行这个进程时,进程调度器就让这个进程从就绪状态进入运行状态。

4)队列

事实上,会有很多的作业和进程相互竞争计算机资源。例如,当一些作业进入内存时,其他的就必须等待一直到有了可用空间。当一个进程正在使用CPU,其他进程就必须等待直到CPU空闲为止。为处理多个进程和作业,进程管理器会使用队列(等待列表)。与每一个作业或进程相关联的是存有这些作业和进程信息的作业控制块或进程控制块。进程管理器在队列中存储的不是作业或进程,而是作业或进程控制块。作业和进程仍保存在内存或硬盘中,它们因为太大而无法被复制到队列里。作业控制块或进程控制块就是等待中的作业和进程的代表。

操作系统有很多队列。例如,作业队列、就绪队列和I/O队列。作业队列用来保存那些等待内存的作业;就绪队列用来保存那些已经在内存中准备好运行但在等待CPU的进程;I/O队列用来保存那些正在等待I/O设备的进程(这里可以有多个I/O队列,每一个对应一个输入/输出设备)。

进程管理器可以用不同策略从队列中选择下一个作业或进程,可以是先入先出(First In First Out,FIFO)、最短长度优先、最高优先级等。

5)进程同步

所有进程管理的思想都是使得拥有不同资源的不同进程同步。只要资源可以被多个用户(进程)同时使用,那么它就有两种状态:死锁和饿死。下面简略说明一下这两种状态。

a. 死锁

先不给出死锁的正式定义,而是看一个例子。假定有两个进程A和B,进程A占有了一个叫做File1的文件(File1已经分配给了A),而它只有得到另一个叫做File2的文件(A已经请求了File2)才能够释放File1。进程B占有了一个叫做File2的文件(File2已经分配给了B),而它只有得到另一个叫做File1的文件(B已经请求了File1)才能够释放File2。在大多数操作系统中,文件都是不可共享的。当文件被一个进程使用时,将不能再被其他的进程使用。在这种情况下,如果没有强制进程释放文件的防备措施,就会发生死锁。

死锁发生在这样的情况下:操作系统允许一个进程运行,而没有首先检查它所需要的资源是否准备好,以及是否允许这个进程占有资源直到它不需要为止。操作系统中需要有一些措施来防止死锁。一种解决方法是当所需资源不空闲时,不允许进程运行。但后面会发现这样做将导致另一个问题。另一种解决方法是限制进程占有资源的时间。

当操作系统没有对进程的资源进行限制时会发生死锁。

死锁不是经常发生,死锁发生需要4个必要条件:互斥(一个资源只能被一个进程占有)、资源占有(尽管并不使用资源,但进程占有着该资源直到有其他可用的资源)、抢先(操作系统不能临时对资源重新分配)、循环等待(所有的进程和资源包含在一个环里)。所有的4个条件都是死锁发生所必需的。但是它们只是必要条件(不是充分条件)。也就是说,对于死锁来说,它们必须出现,但它们并不一定能引起死锁。换句话说,如果它们其中之一没有出现,死锁就不会发生。这样就给我们提供了一种方法来防止或避免死锁:即不让它们中的某一条件发生。

b. 饿死

饿死是一种与死锁相反的情况。它发生在当操作系统对进程分配资源有太多限制时。例如,假如操作系统中规定一个进程只有在所需的所有资源都为其占有时才能执行。假设进程A需要两个文件File1和File2。File1正在被进程B使用,File2正在被进程E使用。进程B首先终止而且释放了Filel,但进程A一直不能执行因为File2一直没有被释放;与此同时,进程C由于只需要File1而被允许执行。这时进程E中止且释放File2,但进程A还是不能执行,因为File1正被使用。

Dijkstra介绍过一个经典的饿死问题。五个哲学家围坐在一个圆桌前,两个哲学家之间有一只筷子,每个哲学家需要用两只筷子来吃碗里的米饭。但一只或两只筷子可能被相邻的人使用。如果没有两只筷子同时可用的话,哲学家将被饿死。

3.设备管理器

设备管理器或输入/输出管理器负责访问输入/输出设备。在计算机系统中,输入/输出设备存在着数量和速度上的限制。由于这些设备与CPU和内存比起来速度要慢很多,所以当进程访问输入/输出设备时,在该段时间内这个设备对其他进程而言是不可用的。设备管理器负责有效使用输入/输出设备。

对设备管理器的详细讨论需要更深入地掌握有关操作系统的高级知识,这些都不在本书讨论范围内。但是可以在这里简要地列出设备管理器的职责。

(1)设备管理器不停地监视所有的输入/输出设备,以保证它们能够正常运行。管理器同样也需要知道什么时候设备已经完成一个进程的服务,而且准备为队列中的下一个进程服务。

(2)设备管理器为每一个输入/输出设备维护一个队列,或者为类似的输入/输出设备维护一个或多个队列。例如,如果系统中有两个高速打印机,管理器能够分别用一个队列维护一个设备,或者用一个队列维护两个设备。

(3)管理器使用不同的方式来访问输入/输出设备。例如,可以用先入先出法来访问一个设备,而用最短长度优先来访问另一个设备。

4.文件管理器

现今的操作系统使用文件管理器来控制对文件的访问。下面简述一下文件管理器的职能。

(1)文件管理器控制对文件的访问。只有那些获得允许的才能够访问,访问方式也可以不同。例如,进程(用户也称为进程)也许可以读取文件,但却不允许写(改变)文件;另一个进程也许被允许执行文件,但却不允许查看文件的内容。

(2)文件管理器管理文件的创建、删除和修改。

(3)文件管理器可以给文件命名。

(4)文件管理器管理文件的存储:怎样存储、存在哪里等。

(5)文件管理器负责归档和备份。

5.用户界面

每个操作系统都有用户界面,即指用来接受用户(进程)的请求并向操作系统的其他部分解释这些请求的程序。一些操作系统的用户界面(如UNIX)被称做命令解释程序(shell)。在其他操作系统中,则被称为窗口,以指明它是一个由菜单驱动的并有着GUI(图形用户界面)的部件。

2.3.4 现代操作系统的特征

在过去数年中,操作系统的结构和功能逐步发展。但是近年来,许多新的设计要素引入到新操作系统及现有操作系统的新版本中,使操作系统产生了本质性的变化。这些现代操作系统的设计要素针对硬件中的新发展、新的应用程序和新的安全威胁。促使操作系统发展的硬件因素主要有:包含多处理器的计算机系统、高速增长的机器速度、高速网络连接和容量不断增加的各种存储设备。多媒体应用、互联网和Web访问、客户/服务器计算等应用领域也影响着操作系统的设计。在安全性方面,互联网的访问增加了潜在的威胁和更加复杂的攻击,如病毒、蠕虫和黑客技术,这些都对操作系统的设计产生了深远的影响。

对操作系统要求的变化速度不仅需要修改和增强现有的操作系统体系结构,而且需要有新的操作系统组织方法。在实验用和商用操作系统中有很多不同的方法和设计要素,大致可以分为以下几类:

● 微内核体系结构;

● 多线程;

● 对称多处理;

● 分布式操作系统;

● 面向对象设计。

至今,大多数操作系统都有一个单体内核(Monolithic Kernel),操作系统应该提供的大多数功能由该单体内核提供,常见功能包括系统调度、文件系统、网络通信、设备驱动、存储管理等。典型情况下,单体内核是作为一个进程实现的,所有元素都共享相同的地址空间。微内核体系结构(Microkernel Architecture)只给内核分配一些最基本的功能,包括地址空间、进程间通信(IPC,Inter-Process Communication)和基本的调度。其他的操作系统服务都是由运行在用户模式下且与其他应用程序类似的进程提供,这些进程可根据特定的应用和环境需求进行定制,有时也称这些进程为服务器。这种方法把内核和服务程序的开发分离开,可以为特定的应用程序或环境要求定制服务程序。微内核方法可以使系统结构的设计更加简单、灵活,很适合于分布式环境。实质上,微内核可以以相同的方式与本地和远程的服务进程交互,使分布式系统的构造更加方便。

多线程(Multithreading)技术是指把执行一个应用程序的进程划分成可以同时运行的多个线程。线程和进程有以下差别。

(1)线程:可分派的工作单元。它包括处理器上下文(包含程序计数器和栈指针)和栈中自己的数据区域(为允许子程序分支)。线程顺序执行,并且是可中断的,这样处理器就可以转到另一个线程。

(2)进程:一个或多个线程和相关系统资源(如包含数据和代码的存储器空间、打开的文件和设备)的集合。这紧密对应于一个正在执行的程序的概念。通过把一个应用程序分解成多个线程,程序员可以在很大程度上控制应用程序的模块性和应用程序相关事件的时间安排。

多线程对执行许多本质上独立、不需要串行处理的任务的应用程序是很有用的,如监听和处理很多客户请求的数据库服务器。在同一个进程中运行多个线程,在线程间来回切换所涉及的处理器开销要比在不同进程间进行切换所涉及的开销少。线程对构造进程是非常有用的。

到现在为止,大多数单用户的个人计算机和工作站基本上都只包含一个通用的微处理器。随着性能要求的不断增加及微处理器价格的不断降低,计算机厂商引进了拥有多个微处理器的计算机。为实现更高的有效性和可靠性,可使用对称多处理(SMP,Symmetric MultiProcessing)技术。对称多处理不仅指计算机硬件结构,而且指反映该硬件结构的操作系统行为。对称多处理计算机可以定义为具有以下特征的一个独立的计算机系统:① 有多个处理器;② 这些处理器共享同一个主存储器和I/O设备,它们之间通过通信总线或其他内部连接方案互相连接;③所有处理器都可以执行相同的功能(因此称为对称)。

对称多处理操作系统可调度进程或线程到所有的处理器运行。对称多处理器结构比单处理器结构具有更多的潜在优势,包括如下几点。

(1)性能:如果计算机完成的工作可组织为让一部分工作并行完成,那么有多个处理器的系统将比只有一个同类型处理器的系统产生更好的性能。对于多道程序设计而言,一次只能执行一个进程,此时所有其他的进程都在等待处理器。对于多处理系统而言,多个进程可以分别在不同的处理器上同时运行。

(2)可用性:在对称多处理计算机中,由于所有的处理器都可以执行相同的功能,因而单个处理器的失败并不会使机器停止。相反,系统可以继续运行,只是性能有所降低。

(3)增量发展:用户可以通过添加额外的处理器来增强系统的功能。

(4)可扩展性:生产商可以根据系统配置的处理器的数量,提供一系列不同价格和性能特征的产品。

特别需要注意的是:这些只是潜在的优点,而不是确定的。操作系统必须提供发掘对称多处理计算机系统中并行性的工具和功能。

多线程和对称多处理总被放在一起讨论,但它们是两个独立的概念。即使在单处理器机器中,多线程对结构化的应用程序和内核进程也是很有用的。由于多个处理器可以并行运行多个进程,因而对称多处理计算机对非线程化的进程也是有用的。但是,这两个设施是互补的,一起使用将会更有效。

对称多处理技术一个极具吸引力的特征是多处理器的存在对用户是透明的。操作系统负责在多个处理器中调度线程或进程,并且负责处理器间的同步。另外一个不同的问题是给一群计算机(多机系统)提供单系统外部特征。在这种情况下,需要处理的是一群实体(计算机),每一个都有自己的主存、辅存和其他I/O模块。分布式操作系统使用户产生错觉,使多机系统好像具有一个单一的主存空间、辅存空间及其他的统一存取措施,如分布式文件系统。尽管集群正变得越来越流行,市场上也有很多集群产品,但分布式操作系统的技术发展水平落后于单处理器操作系统和对称多处理操作系统。

操作系统设计中的另一个改革是使用面向对象技术。面向对象设计的原理用于给小内核增加模块化的扩展。在操作系统一级,基于对象的结构使程序员可以定制操作系统,而不会破坏系统的完整性。面向对象技术还可使分布式工具和分布式操作系统的开发变得更加容易。

2.3.5 Linux和Windows操作系统结构

从操作系统的发展概况中,我们已经知道,UNIX和Windows是两大具有广泛影响的操作系统流派,了解它们可增进对实际操作系统的认识,Linux和Windows 2000是这两大流派中的典型代表,下面简要勾画一下它们的体系结构。

1.Linux操作系统内核结构

图2.14显示了基于IA-64体系结构(如Intel Itanium)的Linux操作系统内核的主要组件。图中显示了运行在内核之上的一些进程。每个方框表示一个进程,每条带箭头的曲线表示一个正在执行的线程。内核本身包括一组相互关联的组件,箭头表示主要的关联。底层的硬件也是一个组件集,箭头表示硬件组件被哪一个内核组件使用或控制。当然,所有的内核组件都在CPU上执行,但是为了简洁,这里没有显示它们的关系。

图2.14 Linux操作系统内核的主要组件

对主要的内核组件的简要介绍如下。

(1)信号(Signals):内核通过信号调用进程。例如,信号用来通知进程某些错误,如被零除错误。

(2)系统调用(System Call):进程是通过系统调用来请求系统服务的。一共有几百个系统调用,可以粗略地分为六类:文件系统、进程、调度、进程间通信、套接字(网络)和其他。

(3)进程和调度器(Processes and Scheduler):创建、管理、调度进程。

(4)虚拟内存(Virtual Memory):为进程分配和管理虚拟内存。

(5)文件系统(File Systems):为文件、目录和其他与文件相关的对象提供一个全局的、层次化的命名空间,并提供文件系统函数。

(6)网络协议(Network Protocols):为用户的TCP/IP协议套件提供套接字接口。

(7)字符设备驱动程序(Character Device Drivers):管理向内核一次发送或接收一个字节数据的设备,如终端、调制解调器和打印机。

(8)块设备驱动程序(Block Device Drivers):管理以块为单位向内核发送和接收数据的设备,如各种形式的辅存(磁盘、CD-ROM等)。

(9)网络设备驱动程序(Network Device Drivers):为网络接口卡和通信端口提供管理,它们负责连接到网桥或路由器之类的网络设备。

(10)陷阱和错误(Traps and Faults):处理CPU产生的陷阱和错误,如内存错误。

(11)物理内存(Physical Memory):管理实际内存中的内存页池并为虚拟内存分配内存页。

(12)中断(Interrupts):处理来自外设的中断。

2.Windows 2000操作系统体系结构

图2.15显示了Windows 2000的体系结构,该版本之后的各种Windows版本在本质上都有相同的结构。模块化结构给Windows 2000提供了相当大的灵活性,它被设计成可以在各种硬件平台上执行、可运行为各种其他操作系统编写的应用程序。

图2.15 Windows 2000体系结构

和其他操作系统一样,Windows 2000把面向应用的软件和操作系统软件分开,后者包括在内核模式下运行的执行体、内核、设备驱动程序和硬件抽象层。内核模块软件可以访问系统数据和硬件,在用户模块下运行的其余软件则被限制访问系统数据。

Windows并不是纯粹的微内核结构,微软将其称为改进的微内核结构。和纯粹的微内核结构一样,Windows是高度模块化的。每个系统函数都正好由一个操作系统部件管理,操作系统的其余部分和所有应用程序通过相应的部件使用标准接口访问这个函数。关键的系统数据只能通过相应的函数访问。从理论上讲,任何模块都可以移动、升级或替换,而不需要重写整个系统或它的标准应用程序编程接口(API)。但是,与纯粹的微内核系统不同,Windows的配置使许多微内核外的系统函数在内核模式下运行,其原因是性能要求。Windows开发者发现,如果使用纯粹的微内核方法,则许多非微内核函数需要进行多次进程或线程切换、模式切换和使用附加的存储器缓冲区。

Windows的内核模式组件包括以下类型。

(1)执行体(Executive):包括操作系统基础服务,如内存管理、进程和线程管理、安全、I/O及进程间通信。

(2)内核(Kernel):包括操作系统中最常用和最基础的组件。内核管理包括线程调度、进程切换、异常和中断处理、多处理器同步。与执行体和用户级的其他部分不同,内核本身的代码并不在线程内执行。因此,内核是操作系统中唯一不可抢占或分页的一部分。

(3)硬件抽象层(Hardware Abstraction Layer,HAL):在通用的硬件命令和响应与某一特定平台专用的命令和响应之间进行映射,它将操作系统从与平台相关的硬件差异中隔离出来,HAL使得每个机器的系统总线、直接存储器访问(DMA)控制器、中断控制器、系统计时器和存储器模块对内核来说看上去都是相同的。它还对对称多处理(SMP)提供支持。

(4)设备驱动程序(Device Drivers):包括文件系统和硬件设备驱动,它把用户I/O函数调用转换为特定硬件设备I/O请求。

(5)窗口和图形系统(Windowing and Graphics System):实现图形用户界面函数(简称GUI函数),如处理窗口、用户界面控制和画图。

Windows执行体包括一些特殊的系统函数模块,并为用户模式的软件提供API。以下是对每个执行体模块的简单描述。

(1)I/O管理器:提供了应用程序访问I/O设备的一个框架,还负责为进一步的处理分发合适的设备驱动程序。I/O管理器实现了所有的Windows I/O API,并实施了安全性、设备命名和文件系统(使用对象管理器)。

(2)Cache管理器:通过使最近访问过的磁盘数据驻留在主存中以供快速访问,以及在更新后的数据发送到磁盘之前,通过在内存中保持一段很短的时间以延迟磁盘写操作,来提高基于文件的I/O性能。

(3)对象管理器:创建、管理和删除Windows执行体对象和用于表示诸如进程、线程和同步对象等资源的抽象数据类型。为对象的保持、命名和安全性设置实施统一的规则。对象管理器还创建对象句柄,对象句柄是由访问控制信息和指向对象的指针组成的。

(4)即插即用管理器:决定并加载为支持一个特定的设备所需的驱动程序。

(5)电源管理器:调整各种设备间的电源管理,并且可以把处理器设置为休眠状态以达到节电的目的。

(6)安全引用监控器:实施访问确认和审计产生规则。Windows面向对象模型允许统一且一致的安全视图,包含组成执行体的基本实体。因此,Windows为所有受保护对象的确认访问和审核检查使用相同的例程,这些受保护对象包括文件、进程、地址空间和I/O设备。

(7)虚拟存管理器:把进程地址空间中的虚地址映射到计算机内存中的物理页。

(8)进程/线程管理器:创建和删除对象,跟踪进程和线程对象。

(9)配置管理器:负责执行和管理系统注册表,系统注册表是保存系统和每个用户参数设置的数据仓库。

(10)本地过程调用(LPC,Local Procedure Call)机制:在单个系统中,以类似于分布式处理中远程过程调用(RPC,Remote Procedure Call)的方式,在应用程序和执行子系统间强制实施客户/服务器关系。

Windows支持如下四种基本的用户模式进程类型。

(1)特殊系统支持进程:包括未作为Windows操作系统一部分而提供的服务,如登录进程和会话管理程序。

(2)服务进程:诸如事件记录器之类的其他Windows服务。

(3)环境子系统:把本地的Windows服务提供给用户应用程序,因而提供一个操作系统环境或个性化支持。目前支持的子系统有Win32、POSIX和OS/2。每个环境子系统包括动态链接库(DLL),它们把用户应用程序调用转换成Windows调用。

(4)用户应用程序:可以是以下五种类型之一:Win32、POSIX、OS/2、Windows 3.1或MS-DOS。