学习笔记10(第十二章)

一、知识点归纳

(一)知识点内容

教材学习内容总结

本章讨论了块设备IO和缓冲区管理;解释了块设备I/O的原理和I/O缓冲的优点;论述了Unix的缓冲区管理算法,并指出了其不足之处;还利用信号量设计了新的缓冲区管理算法,以提高IO缓冲区的缓存效率和性能;表明了简单的PV算法易于实现,缓存效果好,不存在死锁和饥饿问题;还提出了一个比较Unix缓冲区管理算法和PV算法性能的编程方案。

块设备I/O缓冲区

I/O缓冲的基本原理非常简单。文件系统使用一系列I/O缓冲区作为块设备的缓存内存。当进程试图读取(dev,blk)标识的磁盘块时。它首先在缓冲区缓存中搜索分配给磁盘块的缓冲区。如果该缓冲区存在并且包含有效数据、那么它只需从缓冲区中读取数据、而无须再次从磁盘中读取数据块。如果该缓冲区不存在,它会为磁盘块分配一个缓冲区,将数据从磁盘读人缓冲区,然后从缓冲区读取数据。

当某个块被读入时、该缓冲区将被保存在缓冲区缓存中,以供任意进程对同一个块的下一次读/写请求使用。同样,当进程写入磁盘块时,它首先会获取一个分配给该块的缓冲区。然后,它将数据写入缓冲区,将缓冲区标记为脏,以延迟写入,并将其释放到缓冲区缓存中。由于脏缓冲区包含有效的数据,因此可以使用它来满足对同一块的后续读/写请求,而不会引起实际磁盘I/O。

脏缓冲区只有在被重新分配到不同的块时才会写人磁盘。

Unix I/O缓冲区管理算法

  • I/O 缓冲区:内核中的一系列NBUF缓冲区用作缓冲区缓存。每个缓冲区用一个结构体表示。...
  • 设备表:每个块设备用一个设备表结构表示。...
  • 缓冲区初始化:当系统启动时,所有I/O缓冲区都在空闲列表中,所有设备列表和I/O队列均为空。...
  • 缓冲区列表:当缓冲区分配给 (dev, blk) 时,它会被插人设备表的dev_list 中。...

Unix算法的一些具体说明

  1. 数据一致性:为了确保数据一致性,getblk一定不能给同一个(dev,blk)分配多个缓冲区。...
  2. 缓存效果:缓存效果可通过以下方法实现。释放的缓冲区保留在设备列表中,以便可能重用。...
  3. 临界区:设备中断处理程序可操作缓冲区列表,例如从设备表的I/O队列中删除 bp. 更改其状态并调用brelse(bp)。...

Unix算法的缺点

虽然Unix算法非常简单和简洁.但它也有以下缺点。

  • 效率低下:该算法依赖于重试循环。例如,释放缓冲区可能会唤醒两组进程:需要释放的缓冲区的进程,以及只需要空闲缓冲区的进程。...
  • 缓存效果不可预知:在Unix算法中,每个释放的缓冲区都可被获取。如果缓冲区由需要空闲绥冲区的进程获取,那么将会重新分配缓冲区。...
  • 可能会出现饥饿:Unix算法基于“自由经济”原则,即每个进程都有尝试的机会,但不能保证成功。因此,可能会出现进程饥饿。...

PV算法

BUFFER *getb1k(dev,blk):
while(1){
P(free);
//get a free buffer first 
if (bp in dev_1ist){
if (bp not BUSY){
remove bp from freelist;
P(bp);
// lock bp but does not wait
return bp;
// bp in cache but BUSY 
V(free);
// give up the free buffer
P(bp);
// wait in bp queue
return bp;
// bp not in cache,try to create a bp=(dev,blk)
bp = frist buffer taken out of freelist;
P(bp);
// lock bp,no wait
if(bp dirty){
awzite(bp);
// write bp out ASYNC,no wait
continue;
// continue from (1)
reassign bp to(dev,blk);
// mark bp data invalid,not dir 
return bp;
// end of while(1);
brelse(BUFFER *bp),
{
iF (bp queue has waiter)( V(bp); return; }
if(bp dirty && free queue has waiter){ awrite(bp);zeturn;}
enter bp into(tail of) freelist;V(bp);V(free);
}

(二)苏格拉底挑战

1.知识点一


缓冲模式 描述
IOFBF (全缓冲) 对于输出,数据在缓冲填满时被一次性写入。对于输入,缓冲会在请求输入且缓冲为空时被填充。
IOLBF (行缓冲) 对于输出,数据在遇到换行符或者在缓冲填满时被写入,具体视情况而定。对于输入,缓冲会在请求输入且缓冲为空时被填充,直到遇到下一个换行符。
IONBF (无缓冲) 不使用缓冲。每个 I/O 操作都被即时写入。buffer 和 size 参数被忽略。
#include <stdio.h>

int main() {
    FILE *fp;
    char buffer[BUFSIZ];

    fp = fopen("example.txt", "w");

    // 设置为全缓冲
    setvbuf(fp, buffer, _IOFBF, sizeof(buffer));

    // 写入数据到文件
    fputs("Example of full buffering", fp);

    // 更改为行缓冲
    setvbuf(fp, buffer, _IOLBF, sizeof(buffer));

    // 写入更多数据
    fputs("Example of line buffering\n", fp);

    // 更改为无缓冲
    setvbuf(fp, NULL, _IONBF, 0);

    // 写入最后的数据
    fputs("Example of no buffering", fp);

    fclose(fp);

    return 0;
}

2.知识点二



二、问题与解决

(一)问题

从磁盘到缓冲区的数据读写是否也由CPU完成?

如果每次读缓冲区都没有对应的数据,是否相当于直接磁盘I/O?

数据的换入换出算法有哪些?

(二)解决

1、从磁盘到缓冲区的数据读写是否也由CPU完成?

数据从磁盘到缓冲区的传输通常不是由CPU直接执行的。这一过程主要由I/O控制器或直接内存访问(DMA)硬件来处理。当一个I/O请求被发起时,如磁盘读取,I/O控制器会管理数据的实际传输过程,将数据从磁盘移动到内存中的缓冲区。在这个过程中,CPU的作用主要是发起请求、处理中断和控制I/O操作,而不是直接传输数据。这样可以避免CPU在数据传输期间被占用,提高系统效率。

2、如果每次读缓冲区都没有对应的数据,是否相当于直接磁盘I/O?

是的,如果每次尝试从缓冲区读取数据时都没有找到对应的数据(即缓冲未命中),那么系统将不得不从磁盘直接读取数据。在这种情况下,每次数据请求都会导致磁盘I/O操作,这通常比从缓冲区读取数据要慢得多。这种情况正是缓冲区和缓存机制旨在避免的,因为它们的目的是减少对慢速磁盘的直接访问,通过保留常用数据来提高系统性能。

3、数据的换入换出算法有哪些?

数据的换入换出算法,特别是在操作系统中的页面置换算法,用于管理内存中数据的优先级和存储效率。这些算法包括:
(1)最近最少使用(LRU,Least Recently Used):淘汰那些最长时间未被访问的页面。
(2)先进先出(FIFO,First In First Out):按照页面进入内存的顺序来淘汰页面。
(3)时钟(或NRU,Not Recently Used)算法:简化版的LRU,用一种类似于时钟的方式标记各个页面。
(4)最佳置换(OPT,Optimal)算法:理想情况下的算法,淘汰将来最长时间内不会被访问的页面。这种算法在实践中无法实现,但常用于理论分析和比较。
(5)工作集(Working Set)算法:基于局部性原理,保留最近一段时间内被访问的页面。
(6)第二次机会算法:是FIFO的一种改进版,考虑页面的访问情况。

三、实践过程与代码

(一)实践

打开某个文件:

(二)代码

#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
int main (){
    FILE* fd;
    fd=fopen("/src/hello","r");
    if(NULL==fd){
        perror("can not open file");
        return -1;
    }
    return 0;
}
posted @ 2023-11-11 17:12  6666666mjz  阅读(25)  评论(0)    收藏  举报