0%

系统磁盘和IO原理

[toc]

7.5.1 常见磁盘概念#

7.5.1.1 结构#

  • 磁道:可以立即为磁盘上的圈圈
  • 扇区
    1个磁道会划分为多个扇区
    扇区即块(盘块,即上面文件里提到的盘块)
    存储能力受限于内道的最大记录密度
  • 磁盘地址
    地址=(柱面,盘面,扇区号)
    以簇为单位作为各文件的磁盘分配

7.5.1.2 分类#

根据磁头动作,可以分为 固定头磁盘 / 活动头磁盘
根据磁盘是否固定,可分为 固定盘磁盘 / 可换盘磁盘

7.5.1.3 存取时间#

这个时间是衡量磁盘设计好坏的重要因素

  • 寻找时间Ts (先找磁道,即找在圈里的第几层)
    指找到磁道的时间
    Ts = 0.2ms * 跨越磁道数 + st(磁臂启动时间,即扫描的那个东西开始动的时间)

  • 延迟时间(磁道找完,定位扇区,即在圈上的哪个方位)
    定位置某一扇区的时间
    转一圈的时间/2作为延迟时间, 即对转一圈的时间求个平均(毕竟实际速度和扫描算法有关)
    Tr = 1/2r

  • 传输时间(找到位置了,接着开始读数据)
    就是读写数据时间
    扇区占一圈的几分之几 * 转一圈的描述

其实就是磁臂按正常速度扫完这个内容要花的时间。

7.5.2 调度算法#

其实就是收到多个盘块的请求,选择扫描磁道的方法

  • FCFS 先来先服务
    按盘块请求里的顺序来扫描
    适合那种聚在一起的盘块
  • SSTF 最短时间优先
    一直找最近的磁道
    如果频繁收到比较近的磁道,可能造成其他磁道饥饿,无法被访问
  • SCAN 扫描、电梯算法
    从上倒下,再从下到上,再从上到下,扫到请求里的盘块就算检测到。
    对两端的节点不公平,扫描频率会比中间的低
  • C-SCAN 循环扫描算法
    方向固定,每次都是从下往上, 当到达顶部时, 直接快速转回到底部,然后再继续从下往上(快速转回的过程不会响应任何盘块请求)

7.5.3 扇面划分#

  • 交替编号
    1 3 2 4这样编号
    因为读出数据需要时间,这时候如果让磁道继续转动,可能已经移动到后面第2个扇区了。
    但数据又是希望能连续读的,所以交替放,保证读完后,不用再移动,直接用这个区的
  • 错位命名
    第一层磁道的扇区是1 3 2 4
    第二层磁道的扇区是4 1 3 2
    第三层的磁道是 2 4 1 3
    可以看到每一层磁道的扇区,整体都右移了一位
    这是为了减少切换磁道时,重新扫圈的时间

7.5.4 磁盘管理#

7.5.4.1 初始化#

  • 低级格式化
    初始化扇区号和纠错代码(ECC),ECC用于检验磁盘正确性
    物理分区
  • 逻辑格式化
    初始化磁盘数据结构
    分为C\D\E盘, 对linux就是那些opt分区之类的

7.5.4.2 引导块#

磁盘的启动程序会放在磁盘的引导块上

7.5.4.3 坏块#

对于损坏的磁盘块, 他会检测并避免再使用这些坏块。

更多

7.6 IO管理#

7.6.1 IO控制方式#

  • 程序直接控制
  • 中断驱动方式
  • DMA方式
    特点:
    以块位单位
    数据直接进入内存
    开始和结束需要CPU干预,无法通过外设自己完成

DMA会设置4个寄存器:
命令/状态寄存器CR——用于接收CPU发来的控制命令,存储当前状态
内存地址MAR——存放内存地址
数据寄存器DR——暂存数据
数据计数器DC——用于传输计数

工作过程:

  1. CPU收到程序发来的DMA请求——发出控制命令
  2. 启动DMA->DMA存取->结束
  3. 发送中断信号——CPU中断,通知调用程序DMA结束

DMA和中断的区别

  • DMA:是一种无须CPU的参与就可以让外设与系统内存之间进行双向数据传输的硬件机制,使用DMA可以使系统CPU从实际的I/O数据传输过程中摆脱出来,从而大大提高系统的吞吐率.
  • 中断:是指CPU在执行程序的过程中,出现了某些突发事件时CPU必须暂停执行当前的程序,转去处理突发事件,处理完毕后CPU又返回源程序被中断的位置并继续执行。

所以中断和DMA的区别就是DMA不需CPU参与,而中断是需要CPU参与的。

  • 通道控制方式
    是DMA的升级版
    指令单一,和CPU共享内存
    是一种硬件、特殊的处理器,无内存,指令存在主机内存中。
    传输数据的带线啊哦、内存存放位置,通道可以自主决定!
    即比DMA更高级了

7.6.2 IO层次性结构#

从上往下介绍

  1. 用户层IO软件
  • 由用户提供的库函数
  • 需要一系列系统调用
  1. 设备独立性软件
    曹旭哦提供相关调用
  • 功能: 指向设备的共有操作,向用户层提供统一的IO接口(例如unix底层和IO相关的c函数)
  • 支持设备独立,程序和设备可独立切换,不强依赖。
  1. 设备驱动程序
    商家提供
  • 实行系统对设备的具体操作
  • 具体的硬件设备会配置1个驱动
  1. 中断处理程序
  2. 硬件设备

7.6.3 设备控制器(适配器)#

  • 通过寄存器与CPU进行通信
    具有内存映像,占有CPU内存
    寄存器独立编址,采用IO专用地址
  • 功能
    接收、识别CPU的命令
    实现数据交换
    提供设备状态、提供地址识别
  • 组成部分
    与CPU的接口——数据、地址、命令线
    与设备的接口——1个接口一个设备
    IO控制器(地址、命令译码)

更多

7.6.4 IO核心子系统#

  • 是一个进行设备控制的子系统
  • 内核无需做太多的IO设备管理
  • 子系统实现IO调度队列,改善IO的响应时间,比如磁盘调度

7.6.4.1 缓冲区#

磁盘高速缓存: 在内存中开辟单独空间,利用未利用的页做缓冲池

缓冲区的目的:
减少CPU\IO速度的不匹配
减少CPU中断
提高IO和CPU的并行性

缓冲分类

  • 单缓冲:
    IO和CPU之间只有1个缓冲区。 处理数据的时候,可以提前读进来1份。
  • 双缓冲
    2个缓冲区。
    缓冲1满了之后,装2. CPU可以接连取
    缓冲区1满了之后,
  • 循环缓冲
    有一个缓冲循环队列, 有2个指针
    in指针指向空的缓冲,用于进行外部数据的IO输入。
    out指针指向满的缓冲,用于把数据读进系统中
  • 缓冲池
    要用到的时候,就从池中取一个缓冲区。 用完就归还

7.6.4.2 设备分配和挥手机制#

设备分配分类

  • 独占设备——只允许单进程
  • 分时设备——分时交替IO
  • spooling设备——虚拟设备

设备分配表
DCT设备控制表—— 1个控制表代表一个设备。
COCT控制器控制表——与内存交换数据。请求通道服务——指向CHCT
CHCT通道控制表
SDT系统设备表——记录系统中已连接的设备情况
在这里插入图片描述

7.6.4.3 spooling技术(虚拟化设备)#

  • SPOOLing 技术是用于将 I\O 设备进行虚拟化的技术,
  • 它是专门用于欺骗进程的。
  • 就拿打印机举栗吧,我就买了一台打印机,但此时我打开了 word 和 pdf,想要打印 word 和 pdf 中的内容;此时计算机中有2个进程,word 进程和 pdf 进程,这两个进程都认为自己拥有一个打印机,那么是否此时我作为计算机的主人就拥有2台打印机了呢?当然不是啊,我又不是睁眼瞎,我就看到了一台打印机啊
  • 这就是通过虚拟化技术欺骗了2个无知的进程。具体的实现道理我都懂,那么怎么实现欺骗进程的目的呢(也就是怎么实现SPOOLing技术呢)?
  • SPOOLing 技术首先需要提供统一的调用接口,每一个进程都可以调用该接口,这样在进程看了自己是拥有该设备的。需要将磁盘设备和内存作为缓冲区,磁盘设备上的缓冲区称作井,而内存上的缓存区被称作缓冲区。需要一个专门的输入输出进程来实现对 I/O 设备的读写数据。

以向 I/O 设备写数据为例子,做出概念图,如下所示:
在这里插入图片描述

在这里插入图片描述

首先某一个进程(例如 word)调用了统一的接口,然后进入内核。内核例程负责将 word 想要打印的内容做成一个打印申请表,将这个申请表放入打印输出队列中(这个队列在输出井中)。然后由输出进程从打印队列中取打印申请表,根据表格内容将用户数据从磁盘中取出放入内存输出缓冲区,然后再输出到 I/O 设备中。输出进程会不断的查看打印输出队列,直到队列为空,则输出进程被阻塞。

即对于进程来说,看起来都已经输出或者输入了,实际上看还没有响应,有延迟,物理上共用1个设备。逻辑上是2个设备


Q: 讲一下阻塞和非阻塞的区别?(注意没有携带IO,对应的是广义的方法调用时的阻塞和非阻塞)#

A:
阻塞,对应的是执行线程会被挂起,线程时间片暂停执行,有结果了才返回。
非阻塞,线程不会挂起,而是直接返回结果或者异常,让线程调用者自己确认是否完成了读取,因此线程不会挂起。

阻塞和非阻塞的区别就在于:是否需要线程自己轮询检查


Q: 同步和异步的区别?(注意没有携带IO,对应的是广义的方法调用时的同步和异步)#

A:
同步, 调用Io方法时, 必须等结果返回,这个方法才会结束。
异步, 调用io方法时, 不需要等结果。 由接收方进行异步的通知或者发请求,因此线程可以作别的事情了。(与非阻塞IO不同)

同步和异步的区别就在于:是否通过回调函数进行通知确认结果。
综上可知,同步和异步,阻塞和非阻塞,有些混用,其实它们完全不是一回事,而且它们修饰的对象也不相同。


Q: 讲一下五种IO模型#

A:

  1. 阻塞I/O(blocking I/O)
    调用recv()系统函数,阻塞挂起线程
  2. 非阻塞I/O (nonblocking I/O)
    socket才支持,设置非阻塞时, recv是返回错误, 线程不断轮询
  3. I/O复用(select 和poll) (I/O multiplexing)
    本质上是阻塞IO,关键在于可以监听多个端口上的读或写事件,直到有数据可读或可写时,才真正调用I/O操作函数
  4. 信号驱动I/O (signal driven I/O (SIGIO))
    需要绑定一个信号驱动。当数据准备好时,进程会收到一个SIGIO信号,可以在信号处理函数中调用I/O操作函数处理数据
  5. 异步I/O (asynchronous I/O (the POSIX aio_functions))
    当一个异步过程调用发出后,调用者不能立刻得到结果。实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者的输入输出操作。
    需要服务调用方实现通知或者回调机制。
    5051b94487d8d983aa28ebebf6d526af951739fb