摘自:《程序员的自我修养》
操作系统的一个功能是提供抽象的接口,另外一个主要功能是管理硬件资源。
计算机硬件的能力是有限的,比如一个CPU一秒钟能够执行的指令条数是1亿条或是1GB的内存能够最多同时存储1GB的数据。无论你是否使用它,资源总是那么多。当然我们不希望自己花钱买回来的硬件成为摆设,充分挖掘硬件的能力,使得计算机运行得更有效率,在更短的时间内处理更多的任务,才是我们的目标。这对于早期动辄数百万美元的古董计算机来说更是如此,人们挖空心思让计算机硬件发挥所有潜能。一个计算机中的资源主要分CPU、存储器(包括内存和磁盘)和I/O设备,我们分别从这三个方面来看看如何挖掘它们的潜力。
不要让CPU打盹
在计算机发展早期,CPU资源十分昂贵,如果一个CPU只能运行一个程序,那么当程序读写磁盘时,CPU就空闲下来了,这在当时简直就是暴殄天物。所以人们很快编写了一个监控程序,当某个程序无需使用CPU时,监控程序就把另外的正在等待CPU资源的程序启动,使得CPU能够充分地利用起来。这被称为多道程序的方法看似原始,但是它当时确实大大提高了CPU的利用率。
后来经过改进,程序运行变成了一种协作的模式,即每个程序运行一段时间以后都主动让出CPU给其他程序,使得一段时间内每个程序都有机会运行一小段时间,这种程序协作模式叫做分时系统。
多任务系统作为一种更为先进的操作系统模式,由操作系统接管所有硬件资源,并且本身运行在受硬件保护的级别。所有的应用程序都以进程的方式运行在比操作系统权限更低的级别,每个进程都有自己独立的地址空间,使得进程之间的地址空间相互隔离。CPU由操作系统统一进行分配,每个进程根据进程优先级的高低都有机会得到CPU,但是如果运行时间超出了一定的时间,操作系统会暂停该进程,将CPU资源分配给其他等待运行的进程。这种CPU的分配方式叫做抢占式,操作系统可以强制剥夺CPU资源并且分配给它认为目前最需要的进程。如果操作系统分配,给每个进程的时间都很短,即CPU在多个进程间快速地切换,从而造成了很多进程都在同时运行的假象。目前几乎所有现代的操作系统都是采用这种方式,比如我们熟悉的UNIX,Linux,Windows NT,以及Mac Os X等流行的操作系统。
设备驱动
操作系统作为硬件层的上层,他是对硬件的管理和抽象。对于操作系统上面的运行库和应用程序来说,他们希望看到的是一个统一的硬件访问模式。作为应用程序的开发者,我们不希望在开发应用程序的时候直接读写硬件端口、处理硬件中断等这些繁琐的事情。由于硬件之间千差万别,它们的操作方式和访问方式都有区别。所以在操作系统成熟之前,应用程序的程序员需要直接跟硬件打交道。
当操作系统成熟以后,硬件逐渐被抽象成了一系列概念。在UNIX中,硬件设备的访问形式跟访问普通文件的形式一样;在Windows操作系统中,图形硬件被抽象成了GDI,声音和多媒体设备被抽象成了DirectX对象;磁盘被抽象成了普通文件系统;程序员逐渐从硬件细节中解放出来,可以更多关注应用程序本身的开发。这些繁琐的硬件细节全部交给了操作系统,具体地讲是操作系统中的硬件驱动程序来完成。驱动程序可以看做是操作系统的一部分,它往往和操作系统内核一起运行在特权级,但它又与操作系统内核之间有一定的独立性,使得驱动程序有比较好的灵活性。因为PC的硬件多如牛毛,操作系统开发者不可能给每个硬件开发一个驱动程序,这些驱动程序的开发工作通常由硬件生产厂商完成。操作系统开发者为硬件生产厂商提供了一系列接口和框架,凡是按照这个接口和框架开发的驱动程序都可以在该操作系统上使用。