1.作用
在操作系统中,对文件系统的一切存取操作内核都能够通过对磁盘块的读与写来实现;但是,磁盘操作相对于CPU的速度来说过慢,
会使系统的响应时间加长,吞吐率下降;内核通过保存一个在内存中的被称为数据缓存高速缓存(buffer cache)的数据结构缓冲
池来缓存磁盘块;缓冲池中含有最近被使用的磁盘块的数据,通过缓存磁盘块起到减小对磁盘的存取频率的作用
2.操作
buffer cache存在Unix内核中位于文件子系统与块设备驱动程序之间,作为块数据传输的桥梁。当内核需要读取或者写某个磁盘块时,
先从buffer cache中查找该磁盘块,如果该磁盘块存在于buffer cache中,则不需要读取磁盘块,如果不在buffer cache中,则从磁盘
中读取该磁盘块,缓存该磁盘块在buffer cache中,下次读取该块是不需要在读取磁盘
1. 缓冲区的构成: 一个缓冲区由两部分构成—一个含有磁盘块数据的内存数组和一个用来标识该缓冲区的缓存头部
2. 缓存头部(buffer header)
3. 缓冲区的结构
空闲链表: 空闲链表为双向循环链表,连接所有的空闲(即此刻没有正在被使用)的缓冲区
hash队列: hash队列使用逻辑设备号和块号来在常数时间内查找缓冲区
1. getblk算法
getblk算法根据输入的设备逻辑号与块号来获取上锁的含有该磁盘块数据的缓冲区。
该算法先判断该特定的磁盘块的数据是否在缓冲池中,如果不在则分配一个空闲缓冲区。
把一个缓冲区分配给磁盘块时可能出现的的五种情况
2. brelse算法
brelse算法用与释放缓冲区并对缓冲区解锁;该算法先唤醒等待任何一个缓冲区可用的进程,再唤醒等待该缓冲区可用的进程,并在对空闲链表进行操作时提高了处理机执行级别来防止多个进程同时对空闲链表进行操作破坏空闲链表的数据结构,如果该缓存区被标记为"旧",则该算法将该缓冲区放入空闲链表头部。
algorithm brelse
input: locked buffer
output: none
{
wake up all procs: events, waitting for any buffer free;
wake up all process: events, waitting for this buffer to become free;
raise processor execution level to block interrupts;
if (buffer contents vaild and buffer not old)
enqueue buffer at end of free list
else
enqueue buffer at beginning of free list
lower processor excution level to allow interrupts;
unlock(buffer);
}
1. 读磁盘块算法(bread)
读取磁盘块时,先用getblk算法在buffer cache中搜索该磁盘块,如果该磁盘块数据在buffer cache中,则立即返回该磁盘块即可;如果不在buffer cache中,则同步读取磁盘块数据,使用调用磁盘驱动程序,按排一个"读"请求,然后睡眠来等待I/O事件的发生。
algorithm bread
input: file system block number
output: buffer containning data
{
get buffer for block(algorithm getblk);
if (buffer data vaild)
return buffer;
initiate disk read;
sleep(event disk read complete);
return(buffer);
}
2. 读块与提前读 (breada算法)
考虑到局部性原理,使用提前读算法,在同步读取某个磁盘块时,同时异步读取该磁盘块的另一个磁盘块数据到缓冲区中以便在下次读取该缓冲区时不需要同步读写该磁盘块,可以直接在bufffer cache中获取该磁盘块。
algorithm breada /* block read and read ahead */
input: (1) file system block number for immerdiate read
(2) file system block number for asynchronous read
output: buffer containing data for immediata read
{
if (first block not in cache)
{
get buffer for first block (algorithm getblk);
if (buffer data not vaild)
initiate disk read;
}
if (second block not in cache)
{
get buffer for second block (algorithm getblk);
if (buffer data vaild)
release buffer (algorithm brelse);
else
initiate disk read;
}
if (first block was originally in cache)
{
read first block (algorithm bread);
return buffer;
}
sleep(event first buffer contain vaild data);
return buffer;
}
3. 写磁盘块算法(bwrite)
写磁盘算法接受一个缓冲区,然后将该缓冲区的数据写入到磁盘上,如果该缓冲区被标记为"延迟写",则对该缓冲区进行标记,使用brelse算法来释放该缓冲区,不用执行I/O操作;如果没有标记为"延迟写",则使用同步写即可;
algorithm: bwrite
input: buffer
output: none
{
initiate disk write;
if (I/O synchronous)
{
sleep(event I/O complete);
release buffer (algorithm brelse);
}
else if (buffer marked for delayed write)
mark buffer to put at head of free list;
}