在最早期的计算机中,并没有能够称得上是操作系统的服务管理程序,例如早期的串行处理计算机,就是人们把程序一个一个输入进计算机,设定好预计时间,然后让操作系统进行执行。这样的串行处理存在着调度不合理,准备时间长的问题,并不便于使用。
于是人们想方设法希望可以设计出便于使用的操作系统,而到现代,计算机已经普及,大众对于操作系统的要求更加严格,企业和实验室对操作系统的研究需要从交互性,容错性,安全性等各个方面考虑,这也是操作系统逐渐进步走向智能的道路。但是操作系统的设计一共可以总结为三个大目标:方便,有效,易扩展。
如上图,操作系统是连接计算机硬件与用户的桥梁,发展至今其在计算机体系中起着至关重要的作用,我们可以将操作系统视作一个普通的软件,面向普通用户,用户往往不关心计算机硬件,操作系统需要让计算机底层细节对用户透明,提供用户方便的使用体验,包括基本的程序创建,文件管理,I/O控制,内存管理等功能;而对程序员,操作系统需要像程序员隐藏硬件细节,开发通用开发工具、服务、库、接口等。因此操作系统的功能可以列举如下:程序开发,程序运行,I/O设备访问,文件访问控制,系统访问,错误检测和响应,记账。
对于操作系统的扩展性,有着高度要求,因为操作系统需要不断进步,不断扩展以应对新的服务,新的硬件,或者错误纠正等情况的发生,因此操作系统一般多使用模块化的结构,各个模块组件之间相互配合共同完成工作。
最早期的计算机就是利用普通的串行处理完成工作,就是人们把程序一个一个输入进计算机,设定好预计时间,然后让操作系统进行执行,这样的方式有以下两个问题。
1、调度不合理。如果程序没有在预计时间内运行成功则会强制停止,而如果超预期提前执行完毕,用户也不得不等待预计时间结束才可以放入下一个程序。
2、准备时间长。这样的串行处理操作系统需要人们自己加载编译器,源程序,加载目标程序进行连接,在此期间需要安装或拆卸磁带,十分麻烦,一旦失败只能重新来过,因此在程序运行的前期准备阶段要花费大量时间。
批处理操作系统内部使用了一个监控程序,人们将想要执行的程序放入输入设备,监控程序则负责依次自动从输入设备中调入程序进入内存,指挥处理器进行执行,当执行完毕或遇到错误时都会停止当前程序执行,进而调入下一个程序进行执行,执行结果将会放入输出设备。
监控程序此时充当了操作系统的角色,当调入程序时指挥权暂时交给程序,当执行结束或者出错指挥权将重新换回监控程序。这里指挥权仅仅代表当前情况下处理器从哪个程序中读取代码进行执行。
批处理系统已经有了些操作系统的雏形,但是此时的操作系统一次只能读入一个程序放入内存,调度模式也只是简单的顺序调入,因此内存管理以及调度方式相对来说十分简单。但是此时的操作系统已经有了现代操作系统的雏形功能。
1、内存保护。程序读入内存不得访问监控程序的内存区域,如果尝试这样做则将控制权转交监控程序停止当前运行程序,报错。这样的模式类似于如今操作系统的用户态(目态)以及内核态(管态)。用户程序运行在目态,在用户态情况下拥有着对内核态内存的绝对保护,当发生中断、异常、系统调用时系统会从用户态切换为内核态进行系统级处理,可以理解为用户态是普通用户,而内核态则是系统管理员,拥有最高权限。
2、定时器。当一个程序开始运行时即开始计时,当时间到程序还未运行成功则会报错终止。
3、特权指令。当程序想要执行一些特殊指令时,例如I/O指令,此时将会发生错误,管理权移交监控程序,由监控程序代替普通程序执行特权指令。当用户想要执行特权指令时只能请求监控程序代替进行执行。这一点十分类似如今操作系统的系统调用库函数的执行方法,也需要由用户态向内核态的切换。
上述操作系统同一时间内只能将一个程序读入内存进行执行,但是如果当前程序正在进行I/O操作则处理器只能等待程序I/O结束,因此会有大量的处理器空转时间。那么如果我们可以同时向内存中读入多个程序,在一个程序进行I/O时处理器执行另一个程序岂不是会大大提高处理器利用率。因此多道批处理操作系统诞生了。
这种可以同时向内存中读入多个程序的处理称为多道程序设计也称为多任务处理,是现代操作系统的主要方案。
由于多道操作系统需要向内存中读入多个程序因此其对内存的管理,以及作业调度会更加复杂。
分时系统也是多道程序设计的一种,它旨在可以同时完成处理多个交互作业。在这种系统中,多个用户可以通过不同终端登入同一个系统,同时为计算机安排任务,因此可以看作多个用户共享处理器时间,因此称为分时。
在分时系统中每个用户的程序在很多的时间内交替执行,若不计系统开销则每个用户平均只能得到计算机有效速度的1/n。第一个分时系统是麻省理工学院开发的兼容分时系统(CTSS)。CTSS的工作方式十分简单这里不做过多介绍,但是现代操作系统中的Linux
就是典型的分时系统,它允许多个用户通过不同终端连入系统,同时与系统进行交互,但是Windows
则不是分时系统。
分时及多道程序设计引发了操作系统中的许多新问题,例如内存管理,进程保护,权限控制资源分配等。
操作系统的设计是一门综合性极高的学科,经过几十年的发展,操作系统主要在以下四个方面有了理论进展:进程,内存管理,信息保护与安全,调度及资源管理。
在过去数年中操作系统的结构和功能逐步发展,但几年来新一代操作系统引入许多新的设计要素,使得操作系统有了本质的变化,可以分为以下几点。
内核是一个操作系统的核心,它负责完成操作系统内控制管理计算机资源的核心功能,例如进程,调度,内存管理,文件,资源管理等,我们常说的Linux
操作系统有很多发行版本,但是他们的内核都是Linux
内核,Android
操作系统它的内核也是Linux内核
不过在其基础上进行了改进和优化使其可以进入移动端。
内核是一个操作系统的核心,大多数操作系统都是单体内核,及操作系统绝大部分核心功能都由这一个大内核提供,典型情况下这个内核是一个进程。而微内核体系结构只给内核分配一些最基本的功能,例如地址空间,进程间通讯,调度。其他的功能都在用户态运行并和普通程序没有什么区别,因此这些进程可以更具特定需要和环境进行定制,这些进程也被成为服务器。微内核结构的设计分离了内核和服务程序的开发,使得操作系统的结构设计更加简单、灵活,因此多用于分布式操作系统。
在一个分布式系统中,一组独立的计算机展现给用户的是一个统一的整体,就好像是一个系统似的。系统拥
有多种通用的物理和逻辑资源,可以动态的分配任务,分散的物理和逻辑资源通过计算机网络实现信息交换。系统中存在一个以全局的方式管理计算机资源的分布式操作系统。
分布式操作系统需要在各个独立计算机之间进行信息交互,但是由于在不同的计算机系统中,因此基于处理机之间的通信技术都无法被使用,因此使用分布式消息传递以及远程过程调用来进行信息交互。
线程是处理器调度的最小单位,在Linux
中可以看作是一个轻量化进程,进程则可以看作是若干个线程的集合。在同一进程的不同线程中共享代码段,数据段,I/O状态信息等,但也有自己独立的部分例如栈,errno,调度优先级。
多线程对于许多本质上独立不需要串行处理的应用程序很有用,相比多进程其进行调度和切换所造成的开销也会更小。
对称多处理(SMP),是指在一个计算机体系中有多个处理器,并且内核可以在任何一个处理器上执行,系统也可以调度任何一个进程或线程到任何一个处理器上执行。相比单处理器体系结构,SMP系统可以让多个线程达到并行执行的特点,因此对SMP系统与多线程结合可以大大提高计算机的运行效率。现在的计算机操作系统大部分都是采用对称多处理的体系结构,因为我们现在所使用的处理器一般都拥有多个核心,也就是拥有多个处理器共同为我们工作。
但是对称多处理的产生也使得操作系统的设计要考虑更多的因素。因为此时操作系统所要管理的绝不仅仅是一个核心。举个例子相比单处理器体系结构对称多处理操作系统可能会面临两个处理器同时调度同一个进程的情况,为了避免这种情况的发生就需要使用更加高级的调度算法进行调度,当然也可能存在多个处理器同时竞争同一资源的情况,而对于内核来说内核也应该设计成可重入的,保证内核可以同时被多个处理器执行。
而良好的使用多核处理器和多线程可以大大提高计算机工作效率,而其中又有几种可以潜在提高并行方式的方法。我们正在进入一个众核时代。
面向对象技术在操作系统开发方面可以是操作系统开发更具模块化,使得程序员可以定制操作系统,而不会破坏操作系统的完整性,典型的Windows
就极大程度的采用了面向对象技术进行开发。
Windos
操作系统起源于微软应用于个人计算机上的MS-DOS
操作系统,在1985年改名为Windows
,之后通过不断革新到现在已经推出了Windows10
的版本,在每一代操作系统的更新背后都是对操作系统内核结构的改变。
上图显示了Windows8
的总体结构。Windows
分开了面向应用的软件和操作系统核心软件。在内核组件中包括以下类型:执行体,内核,硬件抽象层,设备驱动,窗口和图形系统,其中执行体包括操作系统核心服务,如I/O管理器,高速缓存管理器,对象管理器,即插即用管理器,电源管理器,安全访问监控程序,虚存管理器,进程/线程管理器,配置管理器,本地过程调用。在用户模式中可以运行4中基本用户模式进程特殊系统进程,服务进程,环境子系统,用户应用程序。
这种模型广泛用于分布式计算。但是在Windows
中也使用了这种模型进行构建,环境子系统和Windows
用户模式服务都已通过RPC
与客户端进行通信的进程来实现。客户-服务器体系结构的优点可以简化执行体,提高可靠性,灵活性高,为分布式计算提供基础。
毫无疑问Windows
是典型的支持线程和SMP
的操作系统。
Windows
内核使用C进行编写,但是其采用的设计原理却与面向对象设计密切相关,拥有面向对象设计的基本特征。因此我们可以将内核中的任何东西看成对象,执行体中的对象也叫内核对象,只能被内核访问,这体现了面向对象的封装特征,将限制对象的访问进行了应用。
UNIX
由贝尔实验室进行开发,是Multics
的微缩版,吸收了其很多思想。无疑UNIX
有很多发行版本,其中有商业销售UNIX System Ⅲ
后台这一曹祖西欧i同由进行多次升级变成了UNIX System V
。
早期UNIX
操作系统体系结构如上图。它被设计成只能在单易处理器上运行,缺乏保护数据结构免受多个处理器同时访问的能力;它的内核不通用,只支持一种文件系统、进程调度策略和可执行文件格式;传统UNIX内核不可扩展,不能重用代码,内核设计巨大,且不是模块化的。
随着UNIX
的不断进步升级,现代的UNIX
内核有着如下所示的结构,其已经逐渐开始向模块化进展。
System V Release 4(SVR4)
是一个经过几乎完全重写System V
的内核后而形成的新版本操作系统,这也是最最重要的UNIX
变体。BSD
广泛应用于高效,是许多商业UNIX
产品的基础,应用最广且文档最好的BSD
版本是FreeBSD
,常用于互联网的服务器,防火墙和嵌入式系统中。Solaris
是基于SVR4
的UNIX
版本,最新版是10,也是使用最为广泛且最成功的商用UNIX
版本。
Linux
都不陌生,它最初是IBM PC
上所应用的一个UNIX
变体,它由芬兰的计算机科学专业学生Linus Torvalds
编写。Linux
成功的一大部分原因在于其由免费软件基金FSF
赞助,Linus
在开发内核时使用了GNU
工具,后来他在GPL
下发布了这个内核,因此今天所有的Linux
的发行版都是FSF
的GNU
项目、Linus
的个人努力以及全世界各地很多合作者共同开发的产品。
Linux
是单体内核,这样的缺点是一大块代码中包含所有的操作系统功能,并作为单个进程运行。这也就使得对操作系统任何部分的修改都要重新连接、重新安装,再重新启动系统,因此任何修改都十分困难,Linux
中的这个问题更加尖锐。
但是尽管Linux
是单体的,但由于其特殊的模块结构使得这些模块可用由命令自动加载和卸载,这些相对独立的模块称为可加载模块。Linux
的可加载模块是可以动态链接的,并且其也是可堆叠的,按照层次有序排列。例如一个文件系统就是一个模块。
如图给出了Linux
内核的主要组件。所有内核组件都在CPU上执行,其中包含很多内核组件例如信号,系统调用,进程和调度器,虚存,文件系统,网络协议,字符设备驱动,块驱动设备,网络设备驱动,陷阱和错误,物理内存,中断。
顺带一提Linux
是典型的分时多用户操作系统,因此十分适合作为服务器进行使用,方便程序员合作开发,现在绝大部分服务器都是采用Linux
作为操作系统,但是由于Linux
对于用户的交互体验不是很好(应该说并没有Windows
的好),无论是从内核设计还是设计理念来看都是Windows
操作起来更加方便因此广泛应用于家用机,如果不是有特殊情况并不建议使用Linux
作为家用操作系统。
Android
操作系统广泛应用于触屏移动设备,其也是基于此目的进行设计和开发的,其早期由Android
公司开发,该公司随后被Google
收购,
Android
是一个包括操作系统内核、中间件和关键应用的软件栈。其因该算是一种嵌入式Linux
,基本框架如图所示。
体系结构如上图所示,在进行开发时,开发者最关心应用及框架,他们通常使用Java
进行开发,在这一层有着访问底层服务的API。对于Android
系统服务,框架中大部分能够调用系统服务的接口都已经向开发者开放,而系统服务分为两部分,媒体服务以及系统服务。
对于Android
的内核是对原生Linux
进行了裁剪,并且针对移动设备提高了内核的功能,可以说Android
有着一颗Mini Linux
内核。
综上我们通过操作系统设计目标,设计重点,操作系统发展历史,以及现代操作系统中新加入的设计元素以及常用现代操作系统对操作系统进行了概述,当然这只是粗略了,甚至只能说是大体上进行了了解,本系列会重点对操作系统原理进行进一步梳理和归纳。参考资料及图均来自《操作系统-精髓与设计原理(第八版)》。