资源描述
Click to edit Master title style,Click to edit Master text styles,Second level,Third level,Fourth level,Fifth level,*,*,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,*,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,*,第 9 章,文件和设备管理示例,1,第1页,9.1,UNIX,文件系统特点与文件类别,9.1.1,UNIX操作系统特点,P,227,UNIX采取树型目录结构。UNIX中一个文件绝对路径名由斜杠“/”开头,随即是路径中所经过全部目录名,中间用斜杠分隔而成,比如:/usr/bin/spell。因为UNIX允许用户设置“当前目录”,所以,从当前目录开始文件路径名,是它相对路径名。,2,第2页,图9.1是它一个经典示例,其中,根目录下有8个子目录:,/dev此目录下都是设备文件,比如键盘终端(con)、打印机(lp)等;,/bin 此目录下是UNIX外壳(shell)中主要程序二进制代码文件;,/usr 此目录下通常为已安装各个子文件系统,如bin、tmp、lib、local、include以及用户各种文件;,/lib 此目录下存放是一些库文件,比如C、PASCAL函数库;,/include 此目录下存放是一些头文件;,/etc 此目录下存放各种管理文件;,/tmp此目录下存放暂时性文件;,/UNIX存放UNIX关键程序。,3,第3页,9.1.2 UNIX文件分类,按照文件内容,UNIX把文件分成3类:,普通文件,:这是通常意义下磁盘文件,即存放用户和系统相关数据和程序那些文件。它们都被视为无结构、无统计概念字符流,文件长度能够动态增减。,目录文件,:由文件目录项组成文件称为目录文件。这种文件在形式上与普通文件相同,只是系统将其解释成目录。普通地,一个文件目录项应该包含文件名称、文件长度、文件类型、文件在辅存位置以及存取权限等信息。在UNIX中,为了加紧对文件目录搜索速度,便于文件共享,把这些内容划分成两个部分:一个称为该文件索引节点(即文件控制块),简称为,i节点,,它里面存放着这个文件长度、文件类型、文件在辅存位置、存取权限以及共享信息等内容;另一个仍称为文件目录项,但它里面只包含文件名和这个文件索引节点编号。,4,第4页,下列图给出了UNIX文件目录项格式,即用14个字节存放文件名,2个字节存放该文件i节点号(id)。不难看出,在UNIX中,是由文件名查文件目录,由文件目录得到该文件i节点编号,由这个编号得到文件i节点,从而得到该文件相关信息。,文件名,i,节点编号id,5,第5页,设备文件,:在UNIX中,把块存放设备(如磁盘)和字符设备(如键盘、打印机)都视为文件。不过它们只有文件目录和索引节点,并不占用实际物理存放块,所以,有时也称它们为特殊文件。为了检验和处理方便,UNIX总是把全部特殊文件放在名为“dev”目录文件中。,6,第6页,9.2.1 UNIX文件系统存放结构,UNIX中,不论是普通文件还是目录文件,都存放在磁盘上。另外,每个文件,i,节点也存放在磁盘上。下面讲述这些信息在磁盘上怎样分布,UINX怎样来对它们实施管理。,为了使整个文件系统易于扩充和更改,UNIX把文件系统分成基本文件系统和可装卸子文件系统(文件卷)两个部分。基本文件系统和子文件系统都有自己独立目录结构,不过基本文件系统是整个UNIX文件系统基础,是文件系统“根”,它总是被固定在作为根存放设备磁盘上。子文件系统是指存放在可装卸存放介质(如软盘)上文件系统,所以,子文件系统含有可装卸特征。当把它安装到基本文件系统上时,本身独立性消失,与基本文件系统融为一体。比如,用户能够把自己文件系统组织在软盘上成为子文件系统。,9.2,文件系统数据结构及其关系,7,第7页,8,第8页,UNIX把文件存放空间磁盘想象成是一个由连续物理块组成,文件卷,(把每个磁盘或磁带看作是一个文件卷),每个物理块含512个字节。在一个磁盘上,存放着普通文件信息,存放着目录文件信息,存放着文件i节点,还要存放对磁盘存放区管理信息(比如哪些块是空闲,哪些块是已分配等等)。整个磁盘存放区组织结构以下列图示,。,9,第9页,块0用来存放引导程序,它与文件管理关系不大。文件存放器全部资源管理信息(即,filsys,表)存放在块1,它是磁盘管理区。从第2块,K,+1块,存放磁盘上文件i节点内容,这个区域称为索引节点表(区)。索引节点表后面是普通数据存放区,在那里存放普通文件和目录文件信息。显然,在磁盘上,普通数据存放区所占用磁盘空间为最大。下面对管理区中资源管理信息表,filsys,、索引节点区中i节点以及文件目录分别加以介绍。,10,第10页,9.2.2 几个惯用数据结构,资源管理结构filsys,:,用来进行文件空闲块和i节点项分配与回收,包含文件系统空闲块分配用堆栈及i节点分配用数据结构。原理见P,229,i节点,(,索引节点,),:存放文件说明信息和对应标识符BFD.包含:磁盘i节点(dinode,以静态形式存放文件说明信息)、内存活动 i节点(inode,为降低设备开启次数、提升文件操作速度而把磁盘i节复制到内存特定区域),。,每个文件都应有一个唯一磁盘索引节点,文件被打开后,还应有内存索引节点。,11,第11页,目录项,:由文件名和磁盘i节点标识符id组成。,系统打开文件表、用户打开文件表,:统计和控制打开文件用户进程以及统计和控制那些共享同一文件用户进程。其中:,用户打开文件表:,存放打开文件描述符fd;,系统打开文件表:统计打开同一文件不一样进 程和不一样进程所使用不一样打开路径,及其对应读写指针。,文件名,i,节点编号id,12,第12页,资源管理任务:,空闲磁盘块分配,i节点分配,系统打开文件表分配,空闲磁盘块回收,i节点回收,系统打开文件表回收,9.3,资源管理和地址映射,13,第13页,空闲磁盘块管理,UNIX对文件存放空间管理在磁盘上,UNIX总是把文件安排在普通数据存放区。所以,UNIX对文件存放空间管理,即是对磁盘上普通数据存放区管理。前面第7章介绍使用“空闲块链”管理磁盘上空闲块时,曾提及“,成组链接,”法,并说UNIX操作系统就是采取这种方法来管理磁盘上空闲块。这种方法是将若干个(如100)空闲盘块划归为一个组,将每组在中全部盘块号存放在其前一组第一个空闲盘块中,而仅把第一组中全部空闲块号放入超级块(filsys结构)中。,下面简单介绍它实现过程。,14,第14页,在磁盘管理区filsys结构中,有两个内容包括到磁盘空闲块管理,一个是由数组,s_free100,组成一个空闲磁盘块索引表。当一个文件要申请磁盘块时,就到这个索引表中去取得需要空闲块;当一个磁盘块被释放时,就把它还回到这个索引表中。所以,这个索引表中统计是当前系统能够直接分配空闲磁盘块。另一个是,s_nfree,,它统计了s_free 中现有可分配空闲磁盘块数。,从形式上看,利用数组s_free100直接管理100个空闲磁盘块,与利用数组s_inode100直接管理100个空闲i节点相类似,但实际上相差很远。因为除这100个直接管理空闲块外,UNIX对其余空闲块并没有放置不论,而是将它们分组进行链接。详细做法以下列图所表示。,15,第15页,16,第16页,UNIX把磁盘上普通数据存放区中全部空闲块依次分组。为了下面讲述方便,对每一组块都进行分别编号。详细方法是:第1组为99块,编号为199(为何第1组只有99块,后面会给出解释)。从第2组起,每组都是100块,剩下块归并成为最终一组。它们都按099次序进行编号。在图中,从右至左反应了这种分组结构。在图中,假定最终一组中只有52个空闲块,各块编号为051。,分好组以后,总是在后一组第0块中开辟101个位置,依次存放前一组总块数以及前一组中每一块地址。也就是说,相当于总是在后一组中,开辟s_nfree和s_free100所需要位置,用于存放前一组分组信息。,17,第17页,在此,有两组情况要做特殊处理。一个是第1组。在第1组中,实际只有99个空闲块。为了管理需要,把它总块数仍记为100,见图中第2组里s_nfree=100。另外,第一组磁盘块编号是从1开始,所以在相当于第0号磁盘块位置存放一个0,而不是某一个磁盘块地址,见图中第2组中s_free0=0。,18,第18页,另一个要特殊处理是最终一组。因为在最终一组后面已经没有下一组了,所以UNIX就把它全部信息存放在管理块filsys中,即存放在filsyss_nfree和s_free100中。因为现在最终一组只有52个空闲块,所以在filsys中s_nfree取值为52,而且只用到数组s_free100前52个元素,即用s_free0到s_free51存放最终一组52个空闲块地址。,至此,成组链接格局已经完成:在filsyss_free 中,统计了当前直接能够分配52个空闲块。在这52个空闲块第0块中,统计了下一组100个空闲磁盘块地址,下一组100个空闲第0块中,统计了再下一组100个空闲磁盘块地址,如此等等。,19,第19页,在采取“成组链接”法后,怎样分配空闲块,怎样回收空闲块?下面来讨论这两个问题。不论是磁盘空闲块分配还是回收,都是在filsys中空闲磁盘块索引表s_free 中进行,并把它视为一个栈。分配时,做出栈操作;回收时,做进栈操作。,s_nfree中统计值,是s_free 中当前实际有空闲块数,恰好也是空闲磁盘块索引表s_free 中下一个能够使用索引表目标下标。,20,第20页,所以,总是先在s_nfree上做减1操作,然后把s_frees_nfree中统计磁盘块分配出去。这里要注意是,假如在s_nfree上做减1操作后,其值等于0了,那么就是要把s_free0所指向那一个磁盘空闲块分配出去。因为它是这一组第0个磁盘块(按照分配次序,它总是在一组中最终被分配出去),里面包含有它前一组空闲块信息在内。所以在把这一块分配出去之前,应该先把它统计101个信息拷贝到filsys结构s_nfree和s_free 里面去,然后才能将它分配出去。,21,第21页,分配时还要注意一个问题是假如分配一直进行,现在要把第2组第0块分配出去。依据前面所说,先把这块中统计101个信息拷贝到filsys结构s_nfree和s_free 里面去,然后才将它分配出去。这意味着系统现在只有最终99块能够分配了。假如分配依然继续,直到把这99块全部分配出去。此时,filsys中s_nfree=1,s_free0=0。若再申请空闲块,s_nfree减1后成为0,即要把s_free0所指块分配出去。此时发觉s_free0=0,而不是一个磁盘块地址,表明全部磁盘空闲块都分配出去了,提出请求进程只能阻塞等候。所以,这就是前面分组时把第1组只分99个空闲块,但依然算这组有100个块,并将第0块指针处安放一个0原因。,22,第22页,进行空闲块回收时,就是将该块地址登记在空闲磁盘块索引表s_frees_nfree表目中,然后让s_nfree加1。不过要注意,在把释放块地址存入索引表s_free 表之前,必须检验s_nfree取值。假如发觉s_nfree等于100,那么表明这时空闲磁盘块索引表在此之前已经搜集满了100个空闲磁盘块,它们应该形成一个新链组。现在要释放一块,是下一组空闲块第0块。于是,就把filsys中s_nfree和s_free0s_free99共101个值存入新释放块中,然后将此块地址填入s_free0中,将s_nfree置为1。,23,第23页,9.3.1 磁盘i节点管理,基本思想,:在给新建文件分配磁盘存放区之前,为其分配磁盘i节点,以将文件相关信息记入其中,并将用户提供文件名和磁盘i节点号一并组成一个新目录项,记入其父目录文件中;删除文件时,回收所分配磁盘i节点项。,分配算法,:借助于i节点线性表利用ialloc算法(UNIX System V)进行,详细分配过程见 P,232,回收算法,:利用ifee算法,24,第24页,9.3.2 内存i节点管理,基本思想,:系统打开文件进行搜索或读写等操作时,为其分配内存i节点,以存放从磁盘i节点拷贝过来信息,方便用户或系统对文件访问;删除文件时,回收所分配磁盘i节点项。,分配,:利用过程iget实现,回收,:利用过程iput实现,25,第25页,9.3.3 系统打开文件表管理,系统打开文件表,:统计打开同一文件不一样进程和不一样进程所使用不一样打开路径,及其对应读写指针。,分配,:利用getf过程实现,回收,:利用closef过程实现,26,第26页,9.3.4 地址映射,前面提及,UNIX文件物理结构采取是索引结构,这种索引结构是经过每个文件i节点中数组di_addr 来形成文件存放索引表。该数组总共有13个元素,每个元素为一个索引项。前10个索引项直接指向文件数据存放磁盘块号,后3个索引项分别组成一次间接索引、二次间接索引和三次间接索引多级索引结构。这么,UNIX能够依据文件大小,经过使用这张存放索引表,形成小型、中型、大型和巨型等不一样规模文件。,27,第27页,小型文件索引结构,:通常,每个磁盘块为512个字节。当一个文件长度在110个磁盘块之间时,就称为小型文件。这时,用文件i节点中数组di_addr 前10个表目,直接指向文件数据存放磁盘块号。所以,在UNIX中,小型文件是经过i节点中数组di_addr 组成一级索引表而取得文件在磁盘上存放位置。,以下列图所表示。,28,第28页,29,第29页,中型文件索引结构,:,当一个文件长度在10138磁盘块内时,就成为一个UNIX中型文件。这时除了用到di_addr0di_addr9外,还要用到di_addr10,以下列图所表示。,在图中,di_addr0di_addr9依然直接指向文件数据存放10个磁盘块号,然后又利用di_addr10指向一个磁盘块。这块并不存放文件数据,而是利用它形成又一级索引。在UNIX中,用4个字节放一个磁盘块号,所以在这个盘块中,能够放128个磁盘块号。这么一来,经过di_addr10提供索引,一个文件就能够到达138个磁盘存放块这么大。,30,第30页,31,第31页,大型和巨型文件索引结构,:当一个文件长度在13816522磁盘块内时,就成为一个UNIX大型文件。这时除了用到di_addr0 di_addr9外,要用到di_addr10,还要用到di_addr11。,在图中,di_addr0di_addr9直接指向文件数据存放10个磁盘块号。然后如同前面那样,利用di_addr10指向一个磁盘块,由它提供128个磁盘块索引,从而使文件总共到达138个磁盘存放块这么大。但这还不够,又利用di_addr11指向一个磁盘块,由它指向128个磁盘块,每个都是一个索引。这么,经过这128个索引、每个指向128个磁盘块,就又能够得到16384个磁盘块。于是,UNIX大型文件最多能够拥有16522个磁盘块(即10+128+16384)。,32,第32页,33,第33页,当一个文件所需磁盘块大于16522个磁盘块时,就成为UNIX巨型文件了。这时除了用到di_addr0di_addr9外,还要用到di_addr10、di_addr11和di_addr12。此时,文件最大长度能够到达约11亿个字节,不过因为此时要经过屡次间接索引,会使系统查找速度大大降低。,34,第34页,9.4,目录与检索方法,目录结构和删除,创建一新文件时,UNIX系统利用makenode过程在其父目录文件中为之结构一个目录项。,目录检索,由namei过程利用散列搜索法完成,其依据用户给出文件路径名,从高层到低层次序地查找各级文件目录,寻找指定文件内存i节点指针。,35,第35页,9.5,文件系统系统调用,UNIX提供了一些系统调用命令,方便用户在程序一级完成对文件操作。相关系统调用是:creat、open、read、write、close、chdir、chown、chmod、link和unlink等。下面对它们各自功效做粗略描述。,creat(建立文件),open(打开文件),close(关闭文件),read(读),write(写),36,第36页,link(链接),系统调用link可认为一个已经存在文件开辟一条新路径,也就是说,可认为一个文件再取一个新名字。它使用格式是:,link(pathname1,pathname2);,其中参数pathname1是原文件路径名,参数pathname2为其新取路径名。,link处理程序先按照参数pathname2指点,将新文件名登记到指定路径目录中。然后根据pathname1,找到原文件所对应i节点编号,将该号填入新文件文件目录中。因为每个文件i节点编号是惟一,所以经过link之后,两个不一样路径名文件就与同一个文件相对应了。,37,第37页,unlink(去链接,),38,第38页,比如考虑上图情形。zong和wang要共同完成一项工作。zong为了访问对方文件x,只能经过“/usr/wang/x”才能到达目标。但假如经过命令:,link(/usr/wang/x,/usr/zong/k);,那么,若当前目录为zong,则zong直接经过k就能够访问wang文件x了,这是因为link命令在zong文件k和wang文件x之间建立了链接缘故。如图(b)所表示。,39,第39页,9.6,UNIX,设备管理,UNIX设备管理概述,UNIX是依据设备与内存之间信息交换单位来对设备进行分类,所以在整个系统中,归到设备管理有两类设备:,块设备,和,字符设备,。前者与内存之间以成组信息为单位进行信息交换,比如硬盘、软盘、磁带都属于块设备。因为这些设备是用来存放信息,所以有时把它们称为存放设备;后者与内存之间以字节为单位进行信息交换,比如键盘输入、显示器和打印机等都属于字符设备之列。因为这些设备主要供计算机接收外部信息,或把加工完成信息传递给外部世界,所以也被称为输入/输出设备。,40,第40页,为了识别每一个详细设备,UNIX是这么做:每一类设备附有一个编号,称为“主设备号”,同类设备中不一样设备也给予一个编号,称为“次设备号”。在请求设备进行输入输出时,必须指定主设备号和次设备号。这么,由主设备号判定由哪个驱动程序工作;驱动程序依据次设备号确定控制哪台设备去完成所需要I/O。,从前面对UNIX文件管理讲述可知,UNIX把块设备和字符设备都视为特殊文件来对待,它们文件目录都在子目录dev下。因为它们是文件,所以有自己i节点。为了与其它文件加以区分,在它们索引节点中,把“文件类型”栏置为“块”或“字符”。由此表明它们不是普通文件,也不是目录文件,而是设备文件,而且由此也能区分是块设备文件还是字符设备文件。,41,第41页,在UNIX中,是经过系统调用creat来建立新文件。但设备文件不能用普通方法来创建,而且也不是谁都有权来创建。假如要创建一个新设备文件,则应该由系统管理员经过系统调用mknod来完成。它使用格式是(P,250,):,mknod(pathname,mode,dev),;,其中,参数pathname是文件路径名,mode指出文件类型(B表示块设备,C表示字符设备),dev是主设备号和次设备号组合。比如有以下命令:,mknod(/dev/abc,C,2 12);,表示要在根目录子目录dev下,创建一个名为abc文件(因为它建立在子目录dev下,所以它是一个设备文件),因为mode=“C”,所以是一个字符设备文件,该设备主设备号是2,次设备号是12。,42,第42页,9.6.1,块设备管理,UNIX在块设备和内存之间安放了缓冲区,经过它使块设备与内存间数据流动在速度上能够匹配,从而到达降低内、外存传输次数目标。如图所表示。对于写操作,先是把内存用户区中数据拷贝到缓冲区,再从缓冲区输出到设备;对于读操作,先从设备接收数据到缓冲区,再将缓冲区中数据拷贝到指定内存用户区。,43,第43页,块设备每一个缓冲区长度为512个字节或1024个字节,这要由文件系统来确定。由一个个缓冲区,组成了供块设备输入/输出使用缓冲池。为了便于管理,UNIX把缓冲池中每个缓冲区分成两个部分:一个是真正用于存放数据部分,一个是用于管理部分。前者仍称为“,缓冲区,”,后者称为“,缓冲区控制块,”,并在缓冲区和缓冲区控制块之间保持一一对应关系。图9.10给出了缓冲区控制块内容和它与缓冲区对应关系。,44,第44页,45,第45页,1,空闲缓冲区队列,(av队列),为了组成系统中空闲缓冲区队列,UNIX设置了一个名为bfreelist控制块,它结构与缓冲区控制块相同,里面av_forw和av_back就是块设备空闲缓冲区队列首指针和尾指针,如图9.11所表示。,46,第46页,47,第47页,对于空闲缓冲区队列,有两点要说明:第一,这个由缓冲区控制块组成队列是一个双向链表,它们经过各自前向指针av_forw和后向指针av_back链接在一起,形成队列。第二,UNIX对这个队列采取先进先出(FIFO)管理算法。即当释放一个缓冲区时,与之对应缓冲区控制块就被链入到空闲缓冲区队列之尾;当申请一个缓冲区时,就把空闲缓冲区队列之首那个缓冲区控制块摘下分配出去,这也就意味着是把这个缓冲区控制块所对应缓冲区分配出去。,48,第48页,2.设备缓冲区队列,(设备b链,散列队列),这是由缓冲区控制块组成第二种队列,是UNIX对缓冲区管理一大特色。下面来说明这是一个什么队列,为何要组成它。,49,第49页,缓冲池中缓冲区资源是有限,为了能够对它们充分地加以利用,以及对它们里面存放数据信息最大程度地加以利用,UNIX提出了这么构想:一个已经在空闲缓冲区队列中缓冲区控制块,在它未被挪为它用之前,它对应缓冲区中保留依然是磁盘上某块中数据信息。假如这时依据需要又要对该磁盘块进行操作,那么大可无须去经过开启I/O取得盘块上数据,这些数据还在原来缓冲区中完好无损地保留着,只要拿来就能够使用。这么做结果是降低了I/O次数,大大提升了系统工作效率。,50,第50页,出自于这些考虑,UNIX一方面依然是让被释放缓冲区所对应缓冲区控制块链入到空闲缓冲区队列之尾,以便能够它用。其次又设置了一个新队列:设备缓冲区队列,即把为某个设备服务缓冲区所对应缓冲区控制块全都汇集在一起,形成了这个设备设备缓冲区队列。一个设备设备缓冲区队列由缓冲区控制块中d_forw和d_back指针进行链接,前者为前向指针,后者为后向指针。该队列首、尾指针是设备表中d_forw和d_back。整个队列如下列图所示。,51,第51页,52,第52页,几点说明:,(1)这个由缓冲区控制块组成队列是一个双向链表,它们经过各自前向指针b_forw和后向指针b_back链接在一起,形成队列。,(2)当一个缓冲区被分配给某个块设备做输入/输出用时,它所对应缓冲区控制块就从队首插入到队列里。,(3)当一个缓冲区控制块插入到一个设备设备缓冲区队列中之后,即便该缓冲区被释放,它也依然在这个队列中排着。这就是说,在任何时刻,UNIX中任何一个缓冲区控制块,总会在空闲缓冲区队列、设备缓冲区队列以及设备输入/输出队列这三个队列中两个里排队,或是在空闲缓冲区队列、设备缓冲区队列里面排着,或是在设备缓冲区队列、设备输入/输出队列里面排着。,(4)只有当一个缓冲区服务对象改变(比如原来被分配给磁盘1使用,现在被分配给磁盘2使用了)时,该缓冲区所对应缓冲区控制块才会从一个设备缓冲区队列上摘下,进入到另一个设备缓冲区队列中;不然即便缓冲区被释放,它依然保持在原来设备缓冲区队列中。,53,第53页,3输入/输出请求队列,(,块设备av链),),当用户对块设备提出输入/输出请求时,首先要申请一个空闲缓冲区控制块(注意:申请到空闲缓冲区控制块,就意味着申请到了存放数据缓冲区,因为它们是一一对应),并把这次输入/输出请求详细要完成任务填入到缓冲区控制块中(数据源地址、目标地址、传输个数等等)。所以,UNIX把向主设备号相同设备提出I/O请求所对应缓冲区控制块链接在一起,形成对这个设备输入/输出请求队列。该队列首指针就是这个设备设备表里d_actf,尾指针是d_actl。以下列图所表示。,54,第54页,55,第55页,对于块设备输入/输出请求队列有三点说明:第一,它是一个单链表,不像空闲缓冲区队列,那里给出是一个双向链表。第二,因为一个缓冲区控制块不可能同时在空闲缓冲区队列和输入/输出请求队列,所以,在输入/输出请求队列中,就借用缓冲区控制块中av_forw指针来组成单链表(这个指针在空闲缓冲区队列里是前向指针)。第三,UNIX对这个队列采取先进先出(FIFO)管理算法。即后到输入/输出请求所对应缓冲区控制块被排在队尾,设备总是为排在队首那个缓冲区控制块中所统计请求服务。服务完一个后,就把它从队首摘下,然后再为下一个请求服务。,56,第56页,9.6.2,字符设备管理,字符设备特点是:工作速度慢;每次传输数量即使不定,但总来说较少;各种设备之间物理差异很大。UNIX为它们输入/输出采取了较为轻易管理字符缓冲技术。,字符设备输入/输出所使用缓冲池,由一个个缓冲区组成,每个缓冲区既含数据存放部分又含管理控制部分,这与块设备缓冲区二者分开管理方法不一样。图9.17给出了字符缓冲区结构示意。,57,第57页,58,第58页,下面对字符缓冲区中各项内容做一些必要说明:,c_next(缓冲区指针)这是一个指向下一个字符缓冲区指针,由它能够形成字符缓冲区各种队列。,c_first(本缓冲区首字符位置)它总是指明当前本缓冲区中存放第1个可用字符所在位置。,c_last(本缓冲区尾字符位置)它总是指明当前本缓冲区中存放最终一个可用字符所在位置。,在这三个信息后面,紧跟着一个64字节大小缓冲数据区。对于字符缓冲区,只有空闲缓冲区队列和设备输入/输出队列。它们分别以下列图(a)、(b)所。,59,第59页,60,第60页,1空闲缓冲区队列,为了形成空闲缓冲区队列,UNIX设置了一个队列首指针cfreelist,它总是指向该队列第1个空闲缓冲区,在队列中全部缓冲区,经过自己c_next指向下一个缓冲区,成为一个单链表。最终一个缓冲区c_next=NULL,表示队列末尾。,UNIX把空闲缓冲区队列视为一个栈来管理,进队列和出队列都是在队首进行。也就是说,申请一个字符缓冲区时,就把该队列中第1个缓冲区摘下分配出去;释放一个缓冲区时,就把它插入到队首。,61,第61页,2输入/输出请求队列,每一个字符设备都有自己设备表,该表中有两个指针:c_cf和c_cl,前者总是指向该设备输入/输出请求队列之首那个缓冲区,后者总是指向该设备输入/输出请求队列之尾那个缓冲区。,62,第62页,对于一个字符缓冲区,c_first是从缓冲区取字符指针,c_last是往缓冲区中存字符指针。比以下列图(a)表示某个字符设备输入/输出请求队列初态。能够看出,此时队列中只有一个缓冲区,该缓冲区中现在还有5个字符,c_first指向当前第1个字符“a”,c_last指向当前最终一个字符“e”。假如现在要从缓冲区中取一个字符,于是依据c_first指点,把字符“a”取出,调整指针c_first指向字符“b”,如图(b)所表示。假如这时需要输入一个字符“f”,因为现在c_last已经指向缓冲区最终了,故应该申请一个新缓冲区,按照指针c_first指点把字符“f”存入,并链入输入/输出队列之尾。这么就从图(b)变成了图(c)。,63,第63页,64,第64页,
展开阅读全文