2011年6月13日星期一

《现代操作系统》一书中的每章节的小结部分,放在这里的算是此书中比较浅显的概括

把每章节的SUMMARY翻译了一下,书是ISBN0-13-031358-0,有976页,这不是该书当前的最新版本。



MODERN OPERATING SYSTEMS
SECOND EDITION
by Andrew S. Tanenbaum

* 0 前言


* 1 介绍
操作系统可以从两个视角来看待:资源管理器和扩产的机器。从资源管理器的角度说,操作系统的工作是有效的管理系统的不同的部分。从扩充的机器的角度说,操作系统的工作是给用户提供一个比真实机器方便使用的虚拟机器。
操作系统有一个很长的历史,从它们代替一般的操作的时候开始,到现代的多程序的系统。重要的包括早期的批处理系统、多程序系统、以及个人计算机系统。
由于操作系统紧紧地和硬件交互,一些计算机硬件的知识对于理解操作系统的有用的。计算机由处理器、储存器以及I/O设备组成。这些部分由总线连接。
所有的操作系统都依赖的概念是进程、内存管理、I/O管理、文件系统和安全。它们都会在随后的章节里处理。
任何操作系统的核心是一系列可以处理的系统调用。它们表明了操作系统实际能做的事情。利于UNX系统,我们接触了一组系统调用。第一组系统调用和进程的创建和终止有关。第二组用来读取和写入文件。第三组用于目录管理。第四组包括其他杂项调用。
操作系统结构可以有多种方式。最常见的为单片机系统、层状层次、虚拟机系统、集成内核或者使用客户机服务器模型。

* 2 进程和线程
为了隐藏中断的作用,操作系统提供了由一系列进程并行运行组成的概念模型。进程可以被动态的创建和终止。每个进程有它自己的地址空间。
对于某些应用让一个进程里有多个线程控制是很有用的。这些线程相互独立地调度并个人有自己的堆栈,但是进程里的所有进程享用共同的地址空间。线程可以实现在用户空间或者内核当中。
进程和使用进程间的通讯机制相互通信,例如信号、监视、或者消息。这些机制用来确保不会有两个进程同时在它们会引起混乱的关键区域。进程可以正在运行、可运行或者阻塞状态,并且可以在自己或者另一个进程运行一个通讯机制的中断的时候改变状态。线程间的通讯也是类似的。
进程间的通讯机制可以解决一些问题、比如生产消费问题、餐饮的哲学家问题、读取器与写入器的问题、以及睡觉的理发师的问题。即使使用了这些机制,仍然需要避免错误和死锁问题。
许多调度算法为人所知。它们中一些原先是用于批处理系统的,例如最短任务优先。另一些则在批处理系统中和交互系统中通用。包括循环调度、优先级调度、多级列队、保障调度、彩票调度、以及公平共享调度。一些系统在调度机制和调度方针之间有明确的划分,这样就可以允许用户来控制调度算法。

* 3 死锁
死锁是任何操作系统中都潜在的问题。它在发生在一组进程中各被授权独立地访问一些资源,并每个进程也需要已经属于该组中其他进程的资源。这些进程被阻塞并都永远不能再运行。
死锁可以通过跟踪什么状态是安全的以及什么状态是不安全的来避免。安全的状态是才能在的一序列时间可以保证所有的进程可以结束。不安全的状态是没有这样的保证。Banker算法可以通过拒接将系统的置于不安全状态的请求来避免死锁。
死锁可以通过建立一种让它永远不会产生的设计来阻止。例如,通过仅允许进程只能同时持有一个资源,死锁的循环等待条件就被打破了。死锁也可以通过给所有的资源编号、并让进程请求资源严格按照递增的顺序。饥饿可以通过先来先服务的分配方针。

* 4 内存管理
在这章中我们探讨了内存的管理。我们看到最简单的系统不交换或分页。一旦程序被载入内存中,它将持续到结束。一些操作系统仅允许某时刻仅有一个进程在内存中,而另一些支持多程序。
下一步是交换。通过交换的应用,系统可以处理比内存空间更多的程序。没有空间的进程交换出到磁盘。内存和磁盘上的自由空间通过位图或者列表的形式跟踪。
现代的计算机通常有某种形式的虚拟内存。在最简单的形式中,每个进程的机制空间划分为称为页面大小一致的块,可以放置到内存中任意可获得的页面帧里面。有许多页面替换算法:两种较好的算法是Aging和WSClock。
页面系统的模型可以看作程序中抽象的页面引用字符串合计使用同样的字符串的不同算法。这些模型可以用来做出一些对分页行为的预测。
为了使分页系统工作良好,选择算法是不够的;还需要注意到一些问题如工作集的决定、内存分配的方针、以及页面的大小。
分段有助于在在执行中处理改变大小的数据结构并简化了连接和共享。它也促成了不同分段的不同保护方式。有时分段和分页是组合在一起提供了二维的虚拟内存模型。MULTICS和Intel Pentium系统支持分段和分页。

* 5 输入/输出
输入/输出是一个常被忽视,但是重要的话题。任何系统中相当大的部分是和I/O相连的。I/O可以通过三种方式来完成。第一种,是可编程了I/O,其中主CPU输入或输出每个字节或字并保持紧张的循环等待直到它能得到或发送下一个数据。第二种是中断驱动的I/O,其中CPU开始对字符或单词的传输后离开去做别的事情,直到中断到达表示I/O完成的信号。第三种是通过DMA,它是一个单独管理用户传输数据块的芯片,只有在整块数据传输完成的时候给出中断。
I/O可以以四个层次来结构:中断服务程序,设备驱动程序、设备无关的I/O软件、以及用户空间中的I/O库和后台程序。设备驱动处理运行设备的细节以及为余下的系统提供一致的接口。设备无关的I/O软件进行缓冲和错误报告之类的事情。
磁盘有多种类型,包括磁性的磁盘、阵列、和各种光盘。磁头的调度算法通常可以用来提升磁盘性能,不过这关系到所呈现的几何形态的复杂度。通过连接两个磁盘,可以构建特定作用属性的稳固储存。
时钟用于跟踪真实事件,限制进程可以运行时间长度、处理看门狗定时器、以及做报告。
面向字符的终端有一些特殊字符可用户输入和一些转义字符用于输出。输入可以在原始模式或者烹饪模式,这取决于程序想对输入有多少控制。输出中的转义序列控制光标的移动,并用户允许插入和删除屏幕上的文字。
许多个人计算机使用GUI来输出。它们基于WMP范式:窗口、图标、菜单、以及指点设别。基于GUI的设备一盘是事件驱动的,通过键盘鼠标以及其他送往程序的事件被尽快地处理。
网络终端有若干形式。其中一种最流行的是运行复杂地用于构建图形界面的X系统。X窗口的另一中方式是使用低层次的接口通过网络传输简单的原始像素。SLIM终端的实验显示这项技术也可以很好的工作。
最后,电源管理是便携计算机的一个主要的问题,因为电池的寿命是有限的。各种技术可被操作系统采用来降低电源的损耗。程序可以通过牺牲一些性能来帮助延长电池的使用时间。

* 6 文件系统
从外面来看,文件系统是文件和目录的集合,加上对它们的操作。文件可以被读取和写入,目录可以创建和销毁,并且文件可以在目录间移动。大部分现代的文件系统支持层次的目录系统,其中目录可以有子目录,并它们循环地继续有子目录。
当从内部来看,文件看起来有很大的不同。文件的设计者必须考虑储存是如何分配,以及系统是如何跟踪哪个块是属于哪个文件。可以的方式包括连续的文件、链接的列表、文件分配表、以及i-node。不同哦你高的系统有不同的目录结构。文件属性可以放在目录中或者其他地方(例如i-node中)。磁盘空间可以使用自由列表或者位图来管理。文件系统的可靠性通过制造增量的转储来增强以及通过让程序可以出错的文件系统。文件系统的性能是重要的并可以用若干方式来增强,包括转存、预读、以及仔细的方式文件块使之间临近。日志结构文件系统也通过大的单元进行写入来增强性能。
文件系统的例子包括ISO 9660、CP/M、MS-DOS、Windows 98、以及UNIX。它们在许多方面有区别,包括如何跟踪哪个块属于哪个文件、目录的结构、以及自由磁盘空间的管理方式。

* 7 多媒体操作系统
多媒体是新起的计算机的使用。由于多媒体文件的大尺寸和它们严格的实时回放需求,为文本设计的操作系统对多媒体不够理想。多媒体文件有多重的平行的轨道组成,通常是一轨视频和至少一轨音频以及有时也有字幕轨。它们必须在播放时同步。
音频的通过定期的采样来录制,通常是44,100次/秒(CD音质)。压制可用于音频信号定义统一的10x的压制速率。视频的压制同时使用帧内压缩(JPEG)和帧间压缩(MEPG),后者用P帧表示与前一帧不同的地方。B帧则居于前一帧或者下一帧。
多媒体需要实时调度已满足期限。两种算法常被采用。第一种是固定速率调度,它使用静态的优先级算法依照周期给进程赋予固定的优先级。第二种是期限最近优先,它是总选择最接近期限的进程的动态算法。EDF较复杂,但是能实现100%的利用率。RMS那样的则不能。
多媒体文件系统通常使用Push模型而不是Pull模型。一旦数据流开始,从磁盘上读取数据就不再要用户请求。这种途径和传统的操作系统有根本的不同,由于对满足实时请求的需要。
文件可以连续的储存或者不是。在后一种情况下,单元是可以可变程度的(一个块是一帧)或者固定长度的(一块有多帧)。这些途径有不同的取舍。
文件在磁盘上的放置影响到性能。当有多个文件的时候,有时organ-pipe算法可以使用。分割文件到多个磁盘上不论横向或纵向,是常见的。块和文件缓存策略也广泛地用来提升性能。

* 8 多处理器系统
计算机系统可以使用多个CPU来更加快速和可靠。三种多CPU系统的组成方式是多处理器、多计算机、以及分布式系统。其中每一种都有自己的特性和问题。
多处理器由两个或更多享用功能的RAM的CPU组成。CPU可以用总线、交叉开关、或者多级交换网络来互联。多种操作系统的配置是可行的,包括给每个CPU单独的操作系统、有一个主操作系统其他作为从属、或者使用对称的对处理器让一份操作系的拷贝可以让任何CPU运行。在后面一种情况,需要用锁来保持同步。当锁不能获得的时候,CPU可以旋转或者做上下文切换。多种调度是可以的,包括时间分时、空间共享、以及成群调度。
多计算机也有两个或者更多的CPU,但是这些CPU有它们自己的私有内存。它们不分享公用的内存,所以所有的通信使用消息的转递,在一些情况,网络接板有它自己的CPU,在这种情况下主CPU和接板的CPU必须自己组织以避免竞争条件。多计算机中用户层次的通讯通常使用远程过程调用,但是分布共享内存也可以使用。处理器局部的平衡是这里的一个问题,并有用于此的多种算法包括发送者启动的算法,接受方启动的算法、以及投标算法。
分布系统是松散耦合的系统,它的每个节点都是有着完整的外围设备和自己的操作系统的独立的计算机。通常这样的系统分布在较广的地理区域。中间件通常构建在操作系统之上来给应用程序提供一致的交互层。各种的中间件包括基于文档的、基于文件的、基于对象的、以及基于协调的中间件。一些例子如World Wide Web、AFS、CORBA、Globe、Linda、以及Jini。

* 9 安全
操作系统可以在许多方面都到威胁,从内部的攻击到从外界进入的病毒。许多攻击是黑客尝试闯入特定的系统,通常仅仅是猜测密码。这些攻击通常只是使用常用密码的字典并惊人的成功。密码安全可以通过使用Salt、一次性密码、以及挑战响应方案。智能卡和生物指示也可以使用。视网膜扫面已经实用了。
许多不同的对操作系统的攻击是一致的,包括特洛伊木马、登录欺骗、逻辑炸弹、陷阱门、以及缓冲溢出攻击。通用的攻击包括请求内存并对其窥探,使用非法的系统调用来看看发生什么,甚至尝试欺骗内部来透露他们不应该透露的信息。
病毒是许多用于增长的严重问题。病毒存在多种形式,包括内存常驻病毒、引导区感染、以及宏病毒。使用病毒扫面器在查找病毒特征是有用的,不过真正好的病毒能加密它们的大部分代码并在每次复制的时候修改余下的代码,使得检测非常困难。一些杀毒软件不仅仅通过查找病毒的特征码来工作,而是通过发现特定可疑的行为。通过安全的计算机使用习惯来避免病毒要优于尝试处理攻击后的后果。简单的说,不要载入执行来历不明的和可信度有疑问的程序。
移动代码是如今必须要处理的问题。把它放在沙箱内,解释运行、以及仅运行可信赖的供应商签名的代码是可行的途径。
系统可以用一个领域(如用户)垂直或者对象水平的矩阵来保护。矩阵可以切割为行,采用基于能力的系统,或者为列,采用基于ACL的系统。
安全的系统是可以被设计的,但是必须从开始就定位一个目标。可能最重要的设计规则是有一个最小的可信赖的计算机基础不能被任何资源的访问绕开。多层安全可以基于Bell-La Padula模型,为保密而设计,或者Biba模型,用于维护系统的完整性。橙皮书描述了可信系统需要满足的要求。最终,即使系统可证明是安全的,仍必须注意到隐蔽的渠道,它能够轻易的通过创建模型外的通信渠道来推翻系统。

* 10 案例1:UNIX和LINUX
UNIX由作为小型机的分时系统开始的,但是现在使用涵盖从笔记本计算机到超级计算机。存在有三个接口:Shell、C库、以及系统调用本身。Shell允许用于键入执行的命令。可以是简单的命令、管道、或者更复杂的结构。输入和输出可以重定向。C库涵盖了系统调用并也有增强的调用,例如printf用于格式化输出往文件。实际的系统调用接口是精简的,大约100个调用,每个调用仅仅做它需要的事情。
UNIX中的关键概念包括进程、内存模型、I/O、以及文件系统。进程可以分出子进程,产生树状的结构。UNIX中的进程管理使用两个关键的数据结构,进程表和用户结构。前者总在内存中,但是后者可以被交换或者分页出去。进程的创建通过复制进程表以及内存镜像来完成。调度使用基于优先级的算法并请相互进程。
内存模型每个进程由三个片段组成,text、data、stack。内存管理曾是用交换来完成,不过现在多数UNIX系统中通过分页来完成。核心地图跟踪每个页面的状态,页面守护进程使用使用时钟算法来保持大约有足有的自由页面。
I/O设备使用特殊的文件来访问,各自有一个主设备号和一个次设备号。块设备I/O使用缓冲缓存来减少访问磁盘的次数。LRU算法可用来管理缓存。字符I/O可以通过直接或者烹制模式。线路规程或流用于给字符I/O添加功能。
文件系统是由文件和目录组成的层次结构。所有的磁盘被载入有单独的根开始的单独的目录树。单独的文件可以链接如一个目录从文件系统的其他地方。要使用文件,必须先打开,产生一个用于读取或者写入的文件描述符。在内部,文件系统使用了三个主要的表:文件描述符表、打开的文件描述符表、以及i-node表。其中i-node表最为重要,包含了关于文件所有的管理信息以及它的块的位置。
保护是基于根据所用者用户组和其他来控制读写执行操作。对于目录,可执行标记解释为搜索的权限。

* 11 案例2:WINDOWS2000
Windows2000的结构是HAL、内核、执行文件、以及一层薄的用于捕获传入的系统调用的系统服务层。此外,有各种设备驱动,包括文件系统和GDI。HAL从上层中隐藏了一定的差异。内核试图给可执行文件隐藏余下的差异使得执行文件是机器独立的。
执行程序是基于内存对象。用户进程创建它们并取回句柄在随后操纵它们。执行组件也能创建对象。对象管理器维护了什么对象可以插入用于以后查找的命名空间。
Windows支持进程、作业、线程和Fiber(用户空间)。进程有虚拟地址空间和资源的容器。线程是执行的单位并由操作系统调度。作业是一组进程用于分配资源的额度。调度通过通过优先级算法让最高优先级的线程随后执行。
Windows2000支持按需分页的虚拟内存。分页算法是基于工作集的概念。系统维护若干自由页面的列表,这样每当页面错误发生,一般有自由页面可用。自由页面列表使用复杂的规则来调整,试图扔掉长时间里没有使用的页面。
I/O通过遵循Windows设备模型的设备驱动完成。每个驱动由初始设备对象开始,其中包含了系统用于添加设备和执行I/O的调用的过程的地址。驱动可以层叠作为过滤器。
NTFS文件系统是基于主文件表,它为每个文件或目录有一项记录。每个文件有多项属性,它可以在MFT记录中不常驻位于磁盘上。NTFS支持压缩和加密,以及其他的功能。
安全是基于访问控制列表。每个进程有访问控制标记来表明它是谁以及如果有的话,它有什么特别的特权。每个对象有一个和它相关的安全描述符。安全描述符指向一个自由访问控制解表,其中有允许或拒绝个人或组访问的访问控制项。
最后,Windows2000为文件系统维护单独系统范围的缓存。这是一个虚拟缓存而不是物理的。磁盘块的请求首先往缓存。如果它们不能满足,则适当的文件系统被调用以获取所需的块。

* 12 操作系统设计
设计一个操作系统有决定它要做什么开始。接口应该是简单、完整、并且高效的。它应该有清晰的用户接口范式、执行范式和数据范式。
系统应该合理地结构,使用一种已知的技术,例如分层或客户服务模式。内部的组件应该相互正交并清晰的从机制中划分出政策。一些问题应该有多思考,例如静态动态的数据结构、命名、绑定时间、以及实现模型的顺序。
性能是重要的,但是优化需要仔细选择而不会破坏系统的结构。空间时间的权衡、缓存、暗示、地区利用、以及优化常见情况是常常值得做的。
由几个人编写的系统不同于300人生产出的大系统。在后一种情况下,团队的结构和项目的管理在项目的成功与失败中扮演了关键的角色。
最终,操作系统不得不继续改变以遵循新的趋势迎接新的挑战。其中包括64位地址空间、大量的连接、桌面多处理器、多媒体、手持的无线计算机、以及种类繁多的嵌入系统。接下来的年份将会是操作系统设计的激动人心的时刻。

* 13 阅读清单和参考书目




*
下面是闲话时间,当前自己对操作系统的了解仅停留在浅浅的层面。关于操作系统方面还缺乏经验和心得,于是这里来说说Java和Scheme语言中多线程的原理和实现吧。这里的侧重是关于用户模式内线程,利用协程以及时间中断来实现多任务的切换。此外要注意到一些系统调用会阻塞整个进程,这也是需要处理的问题。当然,这部分闲话的内容是可以正好来运用一下操作系统方面的知识。

没有评论: