[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——用于传输计数
工作过程:
- CPU收到程序发来的DMA请求——发出控制命令
- 启动DMA->DMA存取->结束
- 发送中断信号——CPU中断,通知调用程序DMA结束
DMA和中断的区别
- DMA:是一种无须CPU的参与就可以让外设与系统内存之间进行双向数据传输的硬件机制,使用DMA可以使系统CPU从实际的I/O数据传输过程中摆脱出来,从而大大提高系统的吞吐率.
- 中断:是指CPU在执行程序的过程中,出现了某些突发事件时CPU必须暂停执行当前的程序,转去处理突发事件,处理完毕后CPU又返回源程序被中断的位置并继续执行。
所以中断和DMA的区别就是DMA不需CPU参与,而中断是需要CPU参与的。
- 通道控制方式
是DMA的升级版
指令单一,和CPU共享内存
是一种硬件、特殊的处理器,无内存,指令存在主机内存中。
传输数据的带线啊哦、内存存放位置,通道可以自主决定!
即比DMA更高级了
7.6.2 IO层次性结构#
从上往下介绍
- 用户层IO软件
- 由用户提供的库函数
- 需要一系列系统调用
- 设备独立性软件
曹旭哦提供相关调用
- 功能: 指向设备的共有操作,向用户层提供统一的IO接口(例如unix底层和IO相关的c函数)
- 支持设备独立,程序和设备可独立切换,不强依赖。
- 设备驱动程序
商家提供
- 实行系统对设备的具体操作
- 具体的硬件设备会配置1个驱动
- 中断处理程序
- 硬件设备
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:
- 阻塞I/O(blocking I/O)
调用recv()系统函数,阻塞挂起线程 - 非阻塞I/O (nonblocking I/O)
socket才支持,设置非阻塞时, recv是返回错误, 线程不断轮询 - I/O复用(select 和poll) (I/O multiplexing)
本质上是阻塞IO,关键在于可以监听多个端口上的读或写事件,直到有数据可读或可写时,才真正调用I/O操作函数 - 信号驱动I/O (signal driven I/O (SIGIO))
需要绑定一个信号驱动。当数据准备好时,进程会收到一个SIGIO信号,可以在信号处理函数中调用I/O操作函数处理数据 - 异步I/O (asynchronous I/O (the POSIX aio_functions))
当一个异步过程调用发出后,调用者不能立刻得到结果。实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者的输入输出操作。
需要服务调用方实现通知或者回调机制。