莱昂氏UNIX源代码分析 第23章 字 符 处 理.pdf
文本预览下载声明
下载
第23章 字 符 处 理
对字符特殊设备提供的缓存是一组 4个字的块,每一块可存放 6个字符。该存储块的原型
是“c b l o c k ”( 8 1 4 0 ) ,其中包含一指向c b l o c k结构的指针,另外一部分是字符数组,其中可存
放6个字符。
另一个重要的数据结构类型为“ c l i s t ”( 7 9 0 8 ) ,其中包含一字符计数器以及头、尾指针,
这种结构用作“c b l o c k ”类型块列表的表头。
当前未用的各“c b l c c k ”通过它们的头指针连接成一个空闲“ c b l o c k ”列表,该列表表头
指针是“c f r e e l i s t ”( 8 1 4 9 ) 。列表中最后一个元素的头指针值为“N U L L ”。
一个“c b l o c k ”列表为一字符列表提供了存储区。“p u t c ”过程的作用是将一个字符加至
这种列表的尾部,“g e t c ”则从列表首取出一个字符。
图2 3 - 1~图2 3 - 4用实例说明了对这种列表增、删字符时,该列表的变化情况。
头 头
尾 尾
图 23-1 图 23-2
开始时假定该列表中已包含 1 4个字符,它们是“ efghijk lmnopqr ”。注意,该列表的头、
尾指针分别指向第 1个字符(在这里是e )和最后 1个字符(在这里是r ) 的位置。若“g e t c ”取走第 1
个字符“e ”,则图2 3 - 1 中列表的情况改变成图2 3 - 2 。字符计数减 1 (从1 4减为 1 3 ),头指针则向
前移动一个字符位置。
如果再从该列表中取走字符“ f ”,则该列表的状况变为图 2 3 - 3 。字符计数再减 1,原先
的第 1 “c b l o c k ”不再包含任何有用信息,已被返回至“ c f r e e l i s t ”列表。现在,该列表的
头指针指向在第 2个“c b l o c k ”中的第 1个字符 ( g ) 。
现在可以提出的一个问题是:当从列表中取出一字符时,如何才能检测出这是第 1种变化
情况,还是第2种情况,从而采取不同的合适处理方法泥 ?
如果读者还没猜想到,那么可以告诉你此问题的答案是:将头指针地址值模除 8 ,然后检
查其结果值。因为在一台二进制计算机上除以 8这种运算是非常容易执行的,因此为什么在每
个“c b l o c k ”中只选择存放6个字符的理由也就十分明显了。
将1个字符加至列表中,使图 2 3 - 3变成图2 3 - 4 。
因为图2 3 - 3 中的最后一个“c b l o c k ”是满的,所以从“ c f r e e l i s t ”中分配一新“c b l o c k ”,
346 下篇 莱昂氏UNIX源代码分析
下载
并将其连接到“c b l o c k ”列表中。在该列表中增加 1个字符后,字符计数和尾指针都作了相应
调整。
头 头
尾 尾
图 23-3 图 23-4
23.1 Cinit(8234)
此过程仅由“m a l i n ”( 1 6 1 3 )调用一次,它将一组字符缓存连接构成“ c f r e e l i s t ”指向的空
闲列表,然后计字符设备类型数。
8 2 3 9 :“c c p ”是在“c f r e e ”数组( 8 1 4 6 ) 中第1个字的地址。
8 2 4 0 :取大于“C C P ”的下一个8 的整倍数,在“c f r e e ”数组中标出取“c b l o c k ”的边界。
注意,从“ c f r e e ”数组中划分出的最后一个“ c b l o c k ”的起始地址要小于等于“
显示全部