第7章I/O设备管理
设备管理是操作系统的主要功能之一,它负责管理所有输人输出设备以完成期望的数据传设备管理可能是操作系统设计中最凌乱的部分,这主要是由于计算机系统中存在着大量的输入/输出设备,其性能和应用特点可能完全不同。所以要建立一个通用的、一致的设备访问接口,使用户和应用程序开发人员能够方便地使用输入/输出设备,而无须关心每种设备各自的特性,这正是设备管理的主要目的。
本章首先讲述设备管理的基本概念,然后讨论I/O硬件组成、I/O软件结构、设备管理的相关技术,最后阐述I/O性能问题及解决方案。
7.1设备与设备分类
输入/输出设备(I/O设备)也称为外部设备(Peripheral Device),有时简称为设备或外设,包括计算机系统中除CPU和内存储器以外的所有的设备和装置,还包括所有外部存储设备。在不同的上下文中,I/O设备一词有广义和狭义两种含义,广义的I/O设备即上述定义,狭义的I/O设备不包括外存设备。
可见,计算机系统中外部设备非常多,并且这些设备在功能、速度和控制方式等方面都有较大的差异,本节将讨论这些问题。
7.1.1设备管理的重要性
为了理解操作系统中设备管理的重要性,首先要了解I/O设备在计算机系统中所起的作用。如果说处理器和内存是计算机系统的大脑部分的话,那么I/O设备就是计算机系统的五官和四肢。各种需要处理的信息和操作人员对计算机系统的操作命令,都要通过输入设备进入计算机系统,处理后的信息和结果也要通过输出设备从计算机系统输出。
计算机系统中的I/O设备种类繁多,从简单的键盘到鼠标、打印机、图形显示终端、磁盘驱动器以至于网络设备,变化万千,造就计算机应用的多样性和普及性。可以说没有I/O设备,就没有计算机的应用。
然而,正如人们已经认识到的,操作系统复杂和庞大的主要原因是它所管理的资源的庞杂和并发技术的采用,而I/o设备的庞杂正是操作系统所管理的资源庞杂的主要原因,I/O设备的速度远低于处理器的速度正是导致并发技术产生的直接原因。
各种外部设备功能和速度的差异以及工作过程的复杂多样性导致了整个硬件I/o过程的复杂多样,再加上用户要求的多样性,CPU进程划分的多样性,就最终导致了具体操作系统的I/O接口和数据结构与算法的多样性。
因此,设备管理在操作系统中具有十分重要的地位,它是操作系统总体性能的重要决定因素、重要表现指标和常见瓶颈之一。
7.1.2设备管理的任务
设备管理的任务主要表现在以下方面:
I/o设备的性能经常成为系统性能的瓶颈。CPU性能越高,I/O设备性能同CPU性能不匹配的反差也越大。如何消解这一矛盾是设备管理的一项重要任务,操作系统主要通过缓冲技术、中断技术和虚拟技术解决这一问题。
I/O设备千变万化,怎样对它们实现统一的管理,从而方便用户使用是设备管理的一项重要任务。为此,操作系统需要在设备管理和系统的其他部分之间提供简单而易于使用的接口,这个接口对于所有设备都应该是相同的,这就是所谓的设备独立性。
用户对I/O设备的使用必须是安全的。对于设备的使用者而言,由设备传送或管理的数据应该是安全和保密的,不能破坏或泄露;对于设备的拥有者而言,多用户多任务环境中的设备使用应该通过协调避免冲突,设备不能被破坏。如何保证安全正确地使用设备,也是设备管理的重要任务。
总之,I/O设备是操作系统所管理的四大类资源之一,设备管理的重要性是不容低估的。
7.1.3设备的分类
计算机外部设备种类繁多,用途各异,现有的各种仪器设备都有可能作为计算机系统的外部设备。为了便于管理,通常从不同角度对设备进行分类。
1.按设备的使用特性分类
按设备的使用特性分类,可以分为I/O设备和存储设备。
I/O设备是计算机与外部世界交换信息的设备。其中,输人设备是计算机用来接受指令和数据等信息的设备,键盘、鼠标等是常见的输入设备;输出设备是计算机用来传送处理结果的设备,常用的输出设备有显示器、打印机等。
在计算机数据采集和过程控制等应用中,各种传感器、传动器、模拟/数字转换器、数字/模拟转换器等也属于I/O设备,这类设备将外部世界的模拟信号转换成计算机能够识别的数字信息输入计算机进行处理,并且将处理结果转换成模拟量以驱动执行结构达到控制的目的。
调制解调器、网络适配器(网络接口卡)等数据通信设备也属于I/O设备,这类设备用于构建计算机网络通信系统。
存储设备是计算机用来存放信息的设备,例如磁带、磁盘、光盘、U盘等各种外存设备。其中,可移动的磁带或磁盘在用于不同机器间传送数据时也可看作是I/O设备。
2.按设备的信息组织方式来划分
按信息组织方式来划分设备,可以把I/O设备划分为字符设备(character device)和块设备(block device)。键盘、终端、打印机等以字符为单位组织和处理信息的设备被称为字符设备;而磁盘、磁带等以数据块为单位组织和处理信息的设备被称为块设备。
划分字符设备和块设备主要是依据设备记录信息的特性,它决定了设备一次操作的数据传送单位和内部是否可寻址。
块设备的基本特性是能够随时读写其中的任何一块而与所有别的块无关。外存类设备通常是块设备,因其记录长度通常为一个数据块,例如磁盘的扇区或者由若干扇区组成的簇。
字符设备通常以字符为单位发送或者接收字符流,而不存在任何块结构。字符设备不可寻址,所以没有任何寻址操作。除磁盘以外的大多数设备,例如网络接口卡、打印机、鼠标等可看作字符设备。
然而,将设备划分成字符设备与块设备的分类方法是不严格而且不完整的,并不是所有的设备都能完全归人其中的某一类,有些设备甚至根本就不进行I/O操作。例如,时钟既不可以按块方式访问,也不产生或接收字符串,它所做的只是按规定好的时间间隔引起中断。
3.按设备的共享属性分类
按设备的共享属性可以将设备分为共享设备、独占设备和虚拟设备。
共享设备是指在一段时间内允许多个进程使用的设备。磁盘是典型的共享设备,若干个进程可以交替地从磁盘上读写信息,假设进程A要从硬盘上读5MB的数据,读完3MB数据时,进程B要求从硬盘读2MB数据,这时磁盘调度算法有可能让进程B先读取它所需要的2MB数据,然后再让A读最后的2MB数据。
独占设备也称为独享设备,是指在一段时间内只允许一个进程使用的设备。也就是说,系统一旦把这类设备分配给某个进程后,便由该进程独占,直到用完释放。打印机是典型的独占设备,假设打印机正在打印进程A的文档,那么在打印进程A的文档的过程中,打印机不能分配给其他进程打印东西,否则打印出来的东西就面目全非了。
独占设备的使用效率低是造成死锁的条件之一,为此引入了虚拟设备的概念。虚拟设备是指利用虚拟技术把独占设备改造成可由多个进程共享的设备。SPOOLing系统是一种非常重要的虚拟设备技术。
7.2 I/O硬件组成
不同的人对于i/o硬件的理解是不同的。对于电子工程师而言,i/o硬件就是芯片、导线、电源、电机和其他组成硬件的物理部件。对程序员而言,则只注意I/O硬件提供给软件的接口,如硬件能够接收的命令、它能够完成的功能以及它能够报告的错误。本节主要介绍怎样对I/O设备编程,而不是如何设计、制造和维护硬件。
7.2.1 计算机I/O系统的结构
从硬件的角度看,一个典型的计算机I/O系统结构如图7-1所示。*部分是CPU和主存,通过总线与第二层的接口(适配器)部件相连,第三层是各种外围设备控制器,最外层是外围设备。图中的外围设备包括输入设备、输出设备、外存设备、数据通信设备和过程控制设备几大类。每一种外围设备在它自己的设备控制器的控制下工作,而设备控制器则通过适配器和主机连接。
每个设备控制器都有若干个寄存器用来与CPU进行通信,包括控制寄存器、状态寄存器和数据寄存器。通过写入控制寄存器,操作系统可以控制设备发送数据、接收数据、开启或关闭;通过读取状态寄存器,操作系统可以获悉设备的状态,如是否准备好接收新的数据;数据寄存器通常作为操作系统可以读写的数据缓冲区。
为了使CPU能够访问设备控制器中的寄存器,必须为每个寄存器分配唯一的地址,该地址称为I/O端口地址或I/O端口号。I/O端口地址主要有两种编址方式:内存映射编址和I/O独立编址。
内存映射编址是分配给系统中所有端口的地址空间与内存地址空间统一编址,处理器把设备控制器中的寄存器看作一个存储单元,对I/o的读写操作等同于对存储器的操作,这样的系统称为内存映射I/O(Memory-Mapped I/O)。大部分处理器采用内存映射I/O。
I/O独立编址是分配给系统中所有端口的地址空间与内存地址空间是完全独立的。采用I/O独立编址的CPU需要使用专门的I/O指令对I/O端口进行操作。
操作系统并不直接与设备本身打交道,而是与设备控制器打交道,也就是说操作系统通过对设备控制器中的寄存器进行读写操作与设备交换数据。于是问题就出现了:如何与设备控制器上的寄存器进行通信,换言之,如何对设备的数据传送进行控制?下面就讨论这一问题。
7.2.2 I/O设备数据传送控制方式
I/O设备的控制方式有程序直接控制方式、中断控制方式、DMA方式和通道控制方式,下面分别介绍这四种控制方式。
1.程序直接控制方式
程序直接控制方式也称为PIO(Programmed I/O,程控I/O)方式,是指由用户进程直接控制内存或CPU和外围设备之间进行信息传送的方式,也称为“忙-等”方式、轮询方式或循环测试方式,这种方式的控制者是用户进程。
当用户进程需要从外围设备输入数据时,它通过CPU发出启动设备准备数据的启动命令(通常是把一个启动位为1的控制字通过数据总线写入设备的控制寄存器中)。然后用户进程进入测试等待状态。在等待时间,CPU不断地用一条测试指令检查设备的状态寄存器是否为完成状态(通常是检测状态寄存器的完成位是否为1),而外围设备只有将输入数据送入数据缓冲寄存器之后,才将该寄存器置为完成状态。当CPU检测到设备的状态寄存器为完成状态,则从设备的数据缓冲寄存器读取数据到内存或CPU。
反之,当用户进程需要向输出设备输出数据时,也必须同样发出启动命令和等待设备准备好之后才能输出数据。
程序直接控制方式的传送结构如图7-2所示。
程序直接控制方式的优点是CPU和外设的操作能通过状态信息得到同步,而且硬件结构比较简单;其缺点是CPU效率较低,传输完全在CPU控制下完成,对外部出现的异常事件无实时响应能力。
所以,程序直接控制方式只适用于那些CPU执行速度较慢,而且外围设备较少的系统,如单片机系统。
2.中断控制方式
中断是在发生了一个异常事件时,调用相应处理程序(通常称为中断服务程序)进行服务的过程。中断源一旦需要CPU为其服务时,就向CPU发出请求,CPU—般在当前指令执行完且状态为允许中断的情况下响应该请求。并由硬件自动关中断(防止在保留断点和程序转移过程中又有新的中断请求发生)、保留断点、转到相应的中断服务程序入口处。然后执行中断服务程序,由软件完成中断服务。中断服务程序结束时,执行中断返回指令返回断点处,继续执行原程序。
中断服务程序与中断时CPU正在执行的进程是相互独立的,相互不传递数据。
采用中断控制方式,可以做到:
(1)CPU与外设在大部分时间内并行工作,有效地提高了计算机的效率。CPU启动外设后,不需要去查询其工作状态,可继续执行主程序,因此两者可并行工作。等外设将数据准备好后,主动申请中断CPU的工作,请求服务。
(2)具有实时响应能力,可适用于实时控制场合。外部中断源始终处于主动地位,随时可请求CPU为其服务。可保证实时控制中现场的许多实时信息随时得到响应。
(3)及时处理异常情况,提高计算机的可靠性。计算机在运行过程中,往往可能出现一些意想不到的情况或发生一些故障。利用中断功能就可以及时进行处理,而不至于造成无可挽回的局面。
如要采用中断方式进行数据传送,则CPU和设备控制器就应具备中断机构。CPU—侧应具备的功能包括:具备识别中断请求的能力,在每条指令执行结束应检测有无中断请求发生;具备响应中断的能力(自动关中断、保留断点、转中断处理程序);当需要时,能拒绝响应外部中断请求;具备按优先级响应中断请求的能力。上述功能需要相应的电路支持,即需要设置寄存中断状态的“中断允许触发器”、能保留断点和恢复断点的具有先进后出功能的堆栈、中断判优电路及其他相关电路。
设备控制器一侧应具备的功能包括:具备寄存外设中断请求的能力——通常中断源发出的中断请求信号是随机的,而CPU并不能立即给予响应,因此每个中断源均需设置一个中断请求触发器,将中断请求信号寄存下来;具备可屏蔽本级中断请求的能力——为了能动态地改变优先级,通常每个中断源设置一个中断屏蔽触发器,由CPU执行指令读写其状态,只有当该触发器信号处于未屏蔽状态时,本中断源的中断请求信号才能被送往CPU,通过屏蔽优先级高的请求信号,就可动态地由编程命令来改变中断源的优先级了。中断控制方式的传送结构如图7-3所示。
中断控制方式的处理过程如下:
(1)CPU通过数据总线发出命令,启动外设工作,当前进程阻塞,调度程序调度其他进程;
(2)外设数据准备好,置位中断请求触发器;
(3)若此时接口中断屏蔽触发器状态为非屏蔽状态,则接口向CPU发中断请求(IR);
(4)接受中断请求,且中断为允许中断状态,则中断判优电路工作;
(5)中断判优电路对优先级最高的中断请求给予响应(INTA),CPU中断正在执行的其他进程,转而执行中断服务程序。
3.DMA方式
与程序直接控制方式相比,中断方式的CPU利用率大大提高。但是,用中断方式交换数据时,每处理一次I/O数据交换都会耗去一定的CPU处理时间,对于一些高速的外围设备以及成组交换数据的情况,仍然显得速度太慢。采用DMA方式可以解决这一问题。
DMA是直接内存访问(Direct Memory Access)的缩写,它是一种完全由硬件执行I/O数据交换的工作方式。在这种方式中,DMA控制器(DMA Controller,DMAC)从CPU完全接管对总线的控制,数据交换不经过CPU,而直接在内存和I/O设备之间进行。采用DMA方式工作时,由DMA控制器向内存发出地址和控制信号,进行地址修改,对传送字的个数计数,并且以中断方式向CPU报告传送操作的结束。
DMA方式的传送结构如图7-4所示。
DMA方式的数据块传送过程可分为三个阶段:传送前预处理、数据传送、传送后处理。
预处理阶段——由CPU执行I/O指令对DMAC进行初始化与启动。
数据传送阶段——由DMAC控制总线进行数据传输。当外设数据准备好后发DMA请求,CPU当前机器周期结束后响应DMA请求,DMAC从CPU接管总线的控制权,完成对内存寻址,决定数据传送的内存单元地址,对数据传送字进行计数,执行数据传送的操作。
后处理阶段——传送结束,DMAC向CPU发中断请求,报告DMA操作结束。CPU响应中断,转人中断服务程序,完成DMA结束处理工作,包括校验数据,决定是否结束传送等。
DMA方式一般用于高速传送成组的数据。其优点是操作均由硬件电路实现,传输速度快;CPU仅在初始化和结束时参与,对数据传送基本上不干预,可以减少大批量数据传输时CPU的开销;CPU与外设并行工作,效率高。但是DMA方式也有一定的局限性,这是因为DMA方式在初始化和结束时仍由CPU控制,因此,在大型计算机系统中,为了进一步减轻CPU的负担和提高计算机系统的并行工作程度,除了设置DMA器件之外,还设置了专门的硬件装置——通道。
4.通道控制方式
通道(channel)是一个特殊功能的处理器,它有自己的指令和程序,可以实现对外围设备的统一管理和外围设备与内存之间的数据传送。引入通道的目的是为了进一步减少数据输入输出对整个系统运行效率的影响。与DMA方式相比,通道方式增加了CPU与通道操作的并行能力;增加了通道之间以及同一通道内各设备之间的并操作能力;用户提供了灵活增加外设的可能性。
按照信息交换方式的不同,一个系统中可以设立三种类型的通道,即选择通道、数组多路通道和字节多路通道。
选择通道是一种高速通道,在物理上它可以连接多个设备,但是这些设备不能同时工作,在某一段时间内通道只能选择一个设备进行工作。选择通道主要用于连接高速外围设备,如磁盘、磁带等,信息以成组方式高速传输。其优点是以数据块为单位进行传输,传输率高;缺点是通道利用率低。
数组多路通道是对选择通道的一种改进,它的基本思想是当某个设备进行数据传送时,通道只为该设备服务;当设备在执行寻址等控制性动作时,通道暂时断开与这个设备的连接,挂起该设备的通道程序,去为其他设备服务,即执行其他设备的通道程序。其优点是同选择通道一样,以数据块为单位进行传输,传输率高;又具有多路并行操作的能力,通道利用率高。缺点是控制复杂。
字节多路通道是一种简单的共享通道,在分时的基础上为多台低速和中速设备服务。它的主要特点是:各设备与通道之间的数据传送是以字节为单位交替进行的,各设备轮流占用一个短的时间片;多路并行操作能力与数组多路通道相同。
由这三种通道组成的数据传送控制结构如图7-5所示。
图7-5通道方式的数据传送结构
通道具有如下功能:
(1)接受CPU的指令,按指令要求与指定的外围设备进行通信。
(2)从内存读取属于该通道的指令,并执行通道程序,向设备控制器和设备发送各种命令。
(3)组织外围设备和内存之间进行数据传送,并根据需要提供数据缓存的空间,以及提供数据存入内存的地址和传送的数据量。
(4)从外围设备得到设备的状态信息,形成并保存通道本身的状态信息,根据要求将这些状态信息送到内存的指定单元,供CPU使用。
(5)将外围设备的中断请求和通道本身的中断请求,按序及时报告CPU。
7.3 I/O软件的特点及结构
设计I/O软件的一个最关键的目标是设备独立性(Device Independence),也就是说,除了直接与设备打交道的低层软件之外,其他部分的软件并不依赖于硬件。i/o软件独立于设备,就可以提高设备管理软件的设计效率,当I/O设备更新时,没有必要重新编写全部I/O软件。在实际应用中,我们看到在一些操作系统中,只要安装了相对应的设备驱动程序,就可以很方便地安装好新的输入/输出设备,甚至不必重新编译就能将设备管理程序移到他处执行。
为此,I/O设备管理软件的结构,其基本思想是分层构造,也就是说把设备管理软件组织成为一系列的层次,其中低层与硬件相关,它把硬件与较高层次的软件隔离开来。而最高层的软件则向应用提供一个友好的、清晰而统一的接口。i/o软件一般可以分为四层:中断处理程序,设备驱动程序,与设备无关的操作系统软件,用户级软件(指用户空间的I/O软件)。至于一些具体分层时细节上的处理,是依赖于系统的,没有严格的划分,只要有利于设备独立这一目标,可以为了提高效率而作出不同的结构安排。
这四层软件中,中断处理程序已经在前面详细介绍过了,下面讨论其他三层软件。
7.3.1设备驱动程序
设备驱动程序是直接同硬件打交道的软件模块,设备驱动程序中包括了所有与设备相关的代码。一般而言,设备驱动程序的功能是从与设备无关的软件中接收抽象的请求,并进行与设备相关的处理。
1.设备驱动程序的特点
设备驱动程序最突出的特点是它与I/O设备的硬件结构密切联系。设备驱动程序是操作系统底层中唯一知道各种输入/输出设备的控制器细节以及其用途的部分。例如,在操作系统中只有硬盘驱动程序才知道磁盘控制器有多少个寄存器以及它们的用途。硬盘驱动程序知道使磁盘正确操作所需要的全部参数,包括扇区、磁道、柱面、磁头、磁头臂的移动、交叉系数、步进电机、磁头定位时间等。
2.设备驱动程序的结构
不同的操作系统对设备驱动程序的结构的要求是不同的。一般而言,在操作系统的相关文档中,都有对设备驱动程序结构方面的统一要求。
显然,设备驱动程序的结构同I/O设备的硬件特性有关。一台彩色显示器的设备驱动程序的结构显然同磁盘设备驱动程序的结构不同。通常一个设备驱动程序对应处理一种设备类型,或者至多一类密切联系着的设备。系统往往对略有差异的一类设备提供一个通用的设备驱动程序。例如,在Solaris中,为磁盘提供一个通用的设备驱动程序cmdk,不同品牌或不同性能的磁盘都可以使用这个设备驱动程序。但是,为了追求更好的性能,厂家往往还提供专为某一种磁盘编写的设备驱动程序。
可见,对于某一类设备而言,是采用通用的设备驱动程序,还是采用专用的设备驱动程序,取决于用户在这台I/O设备上追求的目标。如果把设备安装的便利性放在第一位,那么建议考虑使用该类设备的通用驱动程序;如果优先考虑设备的运行效率,那么当然应该首选专门为这台设备编写的驱动程序。
3.设备驱动程序的工作过程
设备驱动程序首先从与设备无关的软件中接收抽象的读写请求。对于磁盘驱动程序,一条典型的请求是读第n块。如果请求到来时驱动程序空闲,则它立即执行该请求。但如果它正在处理另一条请求,则它将该请求挂在一个等待队列中。
执行一条I/O请求的第一步,是将它转换为更具体的形式。对于磁盘驱动程序,它包含:计算出所请求块的物理地址、检查驱动器电机是否在运转、检测磁头臂是否定位在正确的柱面,等等。简言之,它必须确定需要哪些控制器命令以及命令的执行次序。
一旦决定应向控制器发送什么命令,驱动程序将向控制器的设备寄存器中写入这些命令。某些控制器一次只能处理一条命令,另一些则可以接收一串命令并自动进行处理。
这些控制命令发出后有两种可能。在许多情况下,驱动程序需等待控制器完成一些操作,所以驱动程序阻塞,直到中断信号到达才解除阻塞。另一种情况是操作没有任何延迟,所以驱动程序无须阻塞。后一种情况的例子如:在有些终端上滚动屏幕只需往控制器寄存器中写入几个字节,无需任何机械操作,所以整个操作可在几微秒内完成。
对前一种情况,被阻塞的驱动程序须由中断唤醒,而后一种情况下它根本无须睡眠。无论哪种情况,都要进行错误检查。如果一切正常,则驱动程序将数据传送给上层的设备无关软件。最后,它将向它的调用者返回一些关于错误报告的状态信息。如果请求队列中有别的请求,则它选中一个进行处理,若没有则它阻塞,等待下一个请求。
7.3.2与设备无关的系统软件
除了一些I/O软件与设备相关之外,大部分软件是与设备无关的。至于设备驱动程序与设备无关的软件之间的界限如何划分,则随操作系统的不同而变化。具体划分原则取决于系统的设计者怎样考虑系统与设备的独立性、驱动程序的运行效率等诸多因素的平衡。对于一些按照设备独立方式实现的功能,出于效率和其他方面的考虑,也可以由设备驱动程序实现。图7-6给出了常见的设备无关软件层实现的一些功能。
一般而言,有设备都需要的I/O功能可以在与设备独立的软件中实现。这类软件面向应用层并提供一个统一的接口。
1.统一命名
在操作系统的i/o软件中,对I/O设备采用了与文件统一命名的方法,即采用文件系统路径名的方法来命名设备。那么,谁来区分这些命名同文件一样的i/o设备呢?这与设备独立的软件负责把设备的符号名映射到相应的设备驱动程序上。
举例来说,在UNIX系统中,像/dev/tty00这样的设备名唯一确定了一个特殊文件的I节点,这个I节点包含了主设备号和次设备号。主设备号用于寻找对应的设备驱动程序,而次设备号提供了设备驱动程序的有关参数,用来确定要读写的具体设备。
2.设备保护
对设备进行必要的保护,防止无授权的应用或用户的非法使用,是设备保护的主要作用。
设备保护是与设备命名的机制密切相关的。那么,在操作系统中如何防止无授权的用户存取设备呢?这也取决于具体的系统,比如在MS-DOS中,操作系统根本没有对设备设计任何保护机制。不过在大型的计算机系统中,用户进程对I/O设备的直接访问是完全禁止的。而UNIX系统则采用一种存取权限的模式,对于系统中的I/O设备这类特殊文件提供“rwx”位进行保护,系统管理员可以根据需要为每一个设备设置适当的存取权限。
3.提供与设备无关的逻辑块
在各种I/O设备中有着不同的存储设备,其空间大小、读取速度和传输速率等各不相同。比如,当前台式机和服务器中常用的硬盘,其空间大小在若干T字节。而在掌上电脑和数码相机这一类设备中,则使用闪存这种存储器,其容量一般在数G字节。又如,目前高档的打印机都自带缓冲存储器,它们可能是一个硬盘,也可能是随机存储芯片,也可能是闪存。它们的空间大小、读取速度和传输速率都极不相同。因此,与设备无关的软件就有必要向较高层软件屏蔽各种I/O设备空间大小、处理速度和传输速率各不相同这一事实,而向上层提供大小统一的逻辑块尺寸。
这样,较高层的软件只与抽象设备打交道,不考虑物理设备空间和数据块大小而使用等长的逻辑块。这些差别在这一层都隐藏起来了。
4.缓冲
对于常见的块设备和字符设备,一般都使用缓冲区。对块设备,由于硬件一般一次读写一个完整的块,而用户进程是按任意单位读写数据的。如果用户进程只写了半块数据,则操作系统通常将数据保存在内部缓冲区,等到用户进程写完整块数据才将缓冲区的数据写到磁盘上。对字符设备,当用户进程把数据写到设备的速度快于系统输出数据的速度时,必须使用缓冲。
5.存储设备的块分配
在创建一个文件并向其中填入数据时,通常在硬盘中要为该文件分配新的存储块。为完成这一分配工作,操作系统需要为每个磁盘设置一张空闲块表或位图,这种查找一个空闲块的算法是与设备无关的,因此可以放在设备驱动程序上面的与设备独立的软件层中处理。
6.独占设备的分配和释放
有一些设备,如打印机驱动器,在任一时刻只能被某个进程使用。这就要求操作系统对设备使用请求进行检查,并根据申请设备的可用状况决定是接收该请求还是拒绝该请求。一个简单的处理这些请求的方法是,要求进程直接通过OPEN打开设备的特殊文件来提出请求。若设备不能用,则OPEN失败。关闭这种独占设备的同时释放该设备。
7.出错处理
一般来说出错处理是由设备驱动程序完成的。大多数错误是与设备密切相关的,因此只有驱动程序知道应如何处理(比如,重试、忽略或放弃)。但是也有一些典型的错误不是输入/输出设备的错误造成的,例如由于磁盘块受损而不能再读,驱动程序将尝试重读一定次数,若仍有错误,则放弃重读并通知与设备无关的软件,这样,如何处理这个错误就与设备无关了。如果在读一个用户文件时出现错误,操作系统会将错误信息报告给调用者。若在读一些关键的系统数据结构时出现错误,比如磁盘的空闲块位图,操作系统则需打印错误信息,并向系统管理员报告相应错误。
7.3.3用户空间的I/O软件
一般来说,大部分I/O软件都包含在操作系统中,但是用户程序仍一有一小部分是与库函数连接在一起的,甚至还有在内核之外运行的程序构成。通常的系统调用,包括I/O系统调用,通常先是库函数实现。例如,一个用C语言编写的程序可含有如下的系统调用:
count=write(fd,buffer,nbytes);
在这个程序运行期间,该程序将与库函数write连接在一起,并包含在运行时的二进制程序代码中。显然,所有这些库函数是设备管理I/O系统的组成部分。
通常,这些库函数所做的工作主要是把系统调用时所用的参数放在合适的位置,由其他的I/O过程去实现真正的操作。
在这里,输入输出的格式是由库函数完成的。标准的I/O库包含了许多涉及i/o的过程,它们都是作为用户程序的一部分运行的。例如C语言的printf函数以一个格式串和可能的一些变量作为输入,构造一个ASCII字符串,然后调用write这个系统调用输出这个串。对输入而言,类似的过程是gets,它读入一行并返回一个字符串。
但是,并非所有的用户层I/O软件都是由库函数组成的。SPOOLing系统是另一种重要的处理方法。正如本章前面所言,SPOOLing系统是操作系统中处理独占设备的一种方法。
假设有一台行式打印机,一个进程打开了它,然后很长时间不使用,这样导致了其他进程都无法使用这台打印机进行打印。
解决方法是创建一个特殊进程(称为守护进程Daemon),以及一个特殊目录(称为SPOOLing目录)。当一个进程要打印一个文件时,首先要生成打印的整个文件,将其放在SPOOLing目录下。然后由守护进程完成该目录下文件的打印工作,该进程是唯一一个拥有使用打印机特殊文件权限的进程。而且,通过保护特殊文件以防止用户直接使用的途径,可以解决进程空占打印机的问题。
需要指出的是,SPOOLing技术不仅仅只适用于打印机这类输入/输出设备,还可应用到其他一些情况。例如,在Internet上的电子邮件系统中,成千上万台计算机联在一起。如果要向某人发送邮件,先调用一个称为send的程序,send接到要发出的信件,然后将它送入一个SPOOLing目录,待以后发送。整个邮件系统是运行在操作系统之外的。图7-7总结了I/O软件的所有层次及每一层的主要功能。
图中的箭头给出了I/O部分的控制流。这里举一个读硬盘文件的例子。当用户程序试图读一个硬盘文件时,需要通过操作系统实现这一操作。与设备无关软件检查高速缓存中有无要读的数据块。若没有,则调用设备驱动程序,向i/o硬件发出一个请求。然后,用户进程阻塞等待磁盘操作的完成。当磁盘操作完成时,硬件产生一个中断,转人中断处理程序。中断处理程序检查中断的原因,认识到这时磁盘读取操作已经完成,于是唤醒用户进程取回从磁盘读取的信息,从而结束了此次I/O请求。用户进程在得到了所需的硬盘文件内容之后,继续运行。
7.4典型的丨/〇技术
在I/O设备管理中,为了提高设备和CPU的效率,引入了各种技术。本节介绍其中经常使用的两项技术:缓冲技术和设备分配技术。SPOOLing技术、DMA与通道技术请参见相关章节。
7.4.1缓冲技术
1.缓冲技术的引入
计算机系统中各个部件速度的差异是明显的。*处理机的速度以毫微秒甚至纳秒计,外部设备的处理速度则一般以毫秒甚至秒计。在不同时刻,系统各部分的负荷也常常很不均衡。例如,某进程在一段相当长的时间内可能只是进行计算而无任何I/O操作,有时它又在很短时间内产生大量数据要求输出。虽然中断和通道技术为系统各部分并行工作提供了可能,但是由于*处理机和外部设备速度不匹配以及工作不均衡,它们的并行程度并不能得到充分发挥。
这里先用一个简单例子说明*处理机和外设的工作情况。假设在一段时间内,系统中只有一个用户进程正在使用行式打印机。其工作过程是:
(1)计算并产生一行需打印的信息,它们存放在字符型数组line[LINELENGTH]中。这段时间用Tc表示。
(2)要求系统将line数组中的信息送行式打印机打印。打印所需时间表示为Tlpt。
步骤(1)、(2)可以反复多次,如图7-8(a)所示。各次循环中,Tc可能不同,分别表示为Tc1、Tc2、……打印机打印一行的时间大致相等,都用Tlpt表示。图中实线部分表示进程正在处理机上运行或打印机正在进行打印操作;虚线部分表示该进程主动放弃处理机,处于睡眠等待状态,或者打印机处于空闲状态。从图中可以看出,为了使用行式打印机,处理机调度操作比较频繁,因此也就增加了系统开销,同时,打印机的忙闲程度也很不均勻,不能充分实施并行操作。另外,当行式打印机工作时,line数组所在的数据段也应贮留在内存中,降低了内存的使用效率。
解决上述问题的一种常用技术是设置一定数量的缓冲存储区。例如,在系统中为行式;打印机设置一个缓冲存储区charbuffer[LINELENGTH]。
于是,进程使用行式打印机的过程变成:
(1)计算并产生一行需打印的信息,它们存放在line[LINELENGTH]中。
(2)要求系统将line数组中的信息交行式打印机打印。
(3)系统将line数组中的信息先传送到buffer中,这一工作所需时间记为Tmv,然后命令行式打印机将buffer中的内容打印出来。此后,用户进程恢复执行步骤(1)。
在这种情况下,进程和行式打印机的工作情况如图7-8(b)所示。从图中可以看出,如果Tc大于或等于Tlpt,那么进程就可以连续运行,不必主动放弃处理机。另外,在需要放弃处理机时,由于打印数据已在缓存buffer中,所以进程有关段不必保存在内存中。但是如果Tc远小于Tlpt,那么额外的进程调度还是不可避免的,系统性能的进一步提高会受到限制。
为了进一步提高行式打印机的利用程度并减少进程调度次数,可以继续增加缓存数。图7-8(c)中示出了系统为行式打印机设置了两个缓冲存储区时的工作情况。从中可以看出,只要进程在一段时间内连续产生的需要打印的信息少于缓存容量与打印机在这段时间内能够输出的信息量之和,那么进程就不必主动放弃处理机,打印机也能以正常速度连续工作。
系统中的实际工作情况比上面的例子当然要复杂得多。系统中通常有多个进程并发运行,它们或共享或各独占一个或几个外部设备。为了解决*处理机和外部设备的速度不匹配和负荷不均衡问题,为了提高各种设备的工作效率,增加系统中各部分的并行工作速度,在系统中设置多个可以公用的缓冲存储区是有益的。
我们要指出,缓存技术是以空间换取时间,而且它只能在设备使用不均衡时起到平滑作用。如果在相当长的一段时间内,进程提出的输入/输出要求超出了相应设备不间断工作所能完成的总量,那么一旦缓存已全部存放了I/O信息后,多缓存的作用也就基本消失。
2.缓冲区的设置与管理
缓冲技术是计算机系统中常用的技术。一般,凡是数据到达速度和离去速度不匹配的地方都可以通过设置缓冲区,以缓解处理机与设备之间速度不匹配的矛盾,并减少对CPU的I/o中断次数从而提高资源利用率和系统效率。
缓冲区可以由硬件实现,称为硬缓冲。硬缓冲区通常设置在设备(如打印机)中。
缓冲区也可以由软件实现,即在内存空间中开辟专门用于数据传输过程中暂存数据的区域。以下主要介绍软缓冲的设置和管理。
在操作过程中,通常采用单缓冲、双缓冲、多缓冲和缓冲池技术。
在单缓冲情况下,输入时通道先将数据送入缓冲区,CPU从缓冲区读取数据处理;通道再送入后续数据,如此反复,直到输入任务完成。输出情形正好相反。由于缓冲区属于互斥区,所以单缓冲并不能明显改善CPU与外部设备的并行性。
在双缓冲情况下,分别设置输入缓冲区和输出缓冲区,则CPU和通道可以分别访问两个缓冲区,即在CPU访问一个缓冲区的同时,通道可以访问另一个缓冲区。这就明显提高了效率。
在双缓冲基础上,又发展了多缓冲。即设置一组输入缓冲区和一组输出缓冲区。但由于缓冲区也属于系统中的重要资源,为了提高其利用率,一般将系统中所有缓冲区集中起来统一管理,构成缓冲池(缓冲区队列)。缓冲池属于操作系统空间,用户程序不能直接对其进行操作,只能通过系统调用进入操作来间接使用它们。
7.4.2设备分配技术
在计算机系统中,设备、控制器和通道等资源是有限的,并不是每个进程随时都可以得到这些资源,它首先需要向设备管理程序提出申请,然后由设备管理程序按照一定的分配算法给进程分配必要的资源。如果进程的申请没有成功,就要在资源的等待队列中排队等待,直到获得所需的资源。
下面就来讨论与设备分配相关的数据结构,以及设备分配的一些原则与策略。
1.设备分配算法的数据结构
任何算法的实现都离不开数据结构的支撑,在设备分配算法中也不例外。为了记录系统内所有设备的情况,以便对它们进行有效的管理,引人了一些表结构,如为每个设备(通道、控制器)配置的设备(通道、控制器)控制表等。由于系统的管理、分配方式不同,实际釆用的表结构也不相同,例如通道控制表就只有在采用通道控制方式的系统中才会出现。
在设备分配算法的实现中,常采用的数据结构主要含四张表,即系统设备表SDT(System Device Table)、设备控制表DCT(Device Control Table)、控制器控制表COCT(Controller Control Table)和通道控制表CHCT(Channel Control Table)。这四张表在分配算法中形成了一个有机整体,有效地记录了外设资源在系统中的情况。设备的每一次分配调用都与这四张表有关,下面详细介绍它们的构成。
系统设备表SDT。在SDT表中,每个接入系统中的外围设备都占有一个表目项。登录了该设备的名称、标识及设备控制表DCT的入口地址等相关的信息。SDT表在整个系统中只有一张,全面反映了系统中的外设资源的类型、数量、占用情况等。
设备控制表DCT。系统中的每台设备都有一张设备控制表DCT。在DCT中充分体现出了设备的各方面特征,以及与该设备相连的设备控制器的情况,并保存了控制器块的入口位置。
控制器控制表COCT。每个控制器都有一张控制器控制表COCT,用于登录某控制器的使用分配情况及与该控制器相连的通道的情况。
通道控制表CHCT。CHGT表反映了通道的情况,系统中的每个通道都有一张CHCT。
与设备分配有关的数据结构如图7-9所示。
设备(通道、控制器)等待队列也是与设备分配有关的数据结构,由等待分配资源的进程控制块组成,其组织方式可以按照先来先服务(FIFO)的顺序,也可以按照优先级顺序。
2.设备分配的原则
设备分配的总原则是,一方面要充分发挥设备的使用效率,同时又要避免不合理的分配方式造成死锁、系统工作紊乱等现象,使用户在逻辑层面上能够合理方便地使用设备。
1)考虑设备的特性和安全性
设备的特性是设备本身固有的属性,一般分为独占、共享和虚拟设备等,这在前面对设备的分类中已经作了说明。对不同属性设备的分配方式是不同的,本节稍后分别进行一些简单介绍。
从安全性方面考虑,有安全分配方式和不安全分配方式两种。在安全分配方式中,每当进程发出I/O请求后就进入阻塞状态,直到其I/O操作全部完成时才被唤醒。进程需要的所有资源必须一次性进行分配,分配后即归进程所有,直到操作结束。这种方式排除了死锁“请求和保持”的必要条件,因而是安全的,但是效率比较低,CPU与I/O设备串行工作。而在不安全分配方式中,进程发出I/O请求后继续运行,如果需要还可以发出其他的I/o请求,申请到的设备一旦使用完就立即释放,仅当请求的设备已经被其他进程占用的时候才进入阻塞状态。这种方式提高了运行效率,但是存在造成死锁的可能,因此设备分配程序中应该增加预测死锁的安全性计算,在一定程度上增加了程序的复杂性。
2)设备分配策略
与进程的调度相似,设备的分配也需要一定的策略,通常采用先来先服务(FIFO)和高优先级优先等策略。
先来先服务策略,就是当多个进程同时对一个设备提出I/O请求时,系统按照进程提出请求的先后次序,把它们排成一个设备请求队列,并且总是把设备首先分配给排在队首的进程使用。
高优先级优先策略,就是给每个进程提出的I/O请求分配一个优先级,在设备请求队列中把优先级高的排在前面,如果优先级相同则按照FIFO的顺序排列。这里的优先级与进程调度中的优先级往往是一致的,这样有助于高优先级的进程优先执行、优先完成。
3.独占设备的分配
独占设备每次只能分配给一个进程使用,这种使用特性隐含着死锁的必要条件,所以在考虑独占设备的分配时,一定要结合有关防止和避免死锁的安全算法。
用户使用独占设备的活动如下:
申请,使用,使用,…,使用,释放……
对于申请命令,系统将设备分配给申请者,具体方法如下:
(1)根据申请的设备类型查询系统设备表,找到对应入口;
(2)P(Sm);
(3)查对应的设备表,找一空闲设备并分配。
对于使用命令,系统将转到设备驱动程序完成一次I/O传输。
对于释放命令,系统将设备从占有者手中收回,具体方法如下:
(1)根据释放设备类型查询系统设备表,找到对应入口;
(2)查对应的设备表,找到要释放的设备;
(3)V(Sm) 。
4.共享设备的分配
共享设备是可由若干个进程同时共享的设备,例如磁盘。用户使用独占设备的活动如下:
使用,使用,…,使用······
与独占型设备不同,用户在使用共享设备时并没有明显的申请和释放活动。但是,在每一个使用命令之前都隐含有一个申请命令,在每一个使用命令之后都隐含有一个释放命令,在此隐含的申请命令和隐含的释放命令之间执行了一次I/O传输。例如,对于磁盘而言,是对一个磁盘数据块的读、写。
通常,共享型设备的I/O请求来自文件系统、虚拟存储系统或输入输出管理程序,其具体设备已经确定,因而设备分配比较简单,即当设备空闲时分配,占用时等待。
5.虚拟设备
系统中的独占设备是有限的,往往不能满足诸多进程的要求,因而会引起大量进程由于等待某些独占设备而阻塞,成为系统中的“瓶颈”。另一方面,申请到独占设备的进程在其整个运行期间虽然占有设备,利用率却常常很低,设备还是经常处于空闲状态。为了解决这种矛盾,最常用的方法就是用共享设备来模拟独占设备的操作,从而提高系统效率和设备利用率。这种技术就称为虚拟设备技术,实现这一技术的软、硬件系统被称为SroOLing(Simultaneous Peripheral Operation On Line,外围设备同时联机操作)系统。
SPOOLing系统通常分为输人SPOOLing和输出SPOOLing,两者工作原理类似。下面就以常见的共享打印机为例,说明输出SPOOLing的基本原理。
打印机是一种典型的独占设备,引人SPOOLing技术后,用户的打印请求传递给SPOOLing系统,而并不是真正把打印机分配给用户。SPOOLing系统的输出进程在磁盘上申请一个空闲区,把需要打印的数据传送到里面,再把用户的打印请求挂到打印队列上。如果打印机空闲,就会从打印队列中取出一个请求,再从磁盘上的指定区域取出数据,执行打印操作。由于磁盘是共享的,SPOOLing系统可以随时响应打印请求并把数据缓存起来,这样就把独占设备改造成了共享设备,从而提高了设备的利用率和系统效率。
7.5 I/O性能何題及解决方案小结
I/O性能常常成为系统性能的瓶颈,因此提高I/O性能十分重要。在解决这一问题时的一
个总思路是使CPU利用率尽可能不受I/O的影响。
为达到此目标,可以采用如下各种技术以提高I/O性能:
(1)通过应用缓冲技术,解决传输速度差异的问题。
(2)通过应用异步I/O技术,使CPU不必等待I/O的操作结果。
(3)通过应用DMA和通道部件,使CPU与这些部件能够并行执行。
(4)通过应用虚拟设备技术,减少进程阻塞时间,提高独占设备的利用率。