- 块设备是系统中能够随机(不需要按顺序)访问固定大小数据片的硬件设备,像硬盘
- 字符设备是按照字符流的方式被有序访问,像键盘
IO调度程序
为什么需要IO调度程序:简单的以内核产生请求的次序直接请求的话,磁盘寻址的速度会很慢,性能会很低。IO调度程序会有一定的延迟,对调度队列进行调整
请求队列
一个关于块IO请求的双向链表
Linus电梯(2.4内核,操作系统概念)
- 合并:新请求加入调度队列时,先检查新请求能不能和队列中的请求合并(比如要扫描相邻扇区);合并失败就插入
- 排序:插入时按磁盘位置排序
- 问题:饥饿现象,一直在相近又刚好是磁盘下一个位置插入新请求
最后期限IO调度程序
除了调度队列外还是用另外四个队列
- 两个排序队列分别包含读写请求,根据磁盘物理位置排序
- 两个最后期限队列分别包含相同的读写请求,根据最后期限排序
- 读请求的超时时间比写请求的超时时间短。因为写是异步的(页回写),不会阻塞;读是同步的,大多会阻塞
- 加入调度队列:
- 程序交互从两个排序队列头的取出一个请求放入调度队列尾;如果同时调度读写,会选择读
- 程序还会检查最后期限队列,把超过最后期限的请求放入调度队列尾
- 注意:不保证响应时间,因为检查到超时也只是放入调度队列末尾,但能避免饥饿
- 解决问题:电梯算法的饥饿问题,读优先
预测IO调度程序
最后期限IO调度的一种演变,同样有四个队列,增加了预测启发能力
- 启发预测:
- 请求提交后不会马上处理下一个请求,而是空闲片刻(默认6-7ms)
- 原因:因为大多数进程都会连续提交读请求,避免错过后要等待一定时间才能重新提交
- 解决问题:最后期限IO在写操作繁忙时,还是先进行读请求的操作会导致效率不高。启发给予更好的读响应
- 适合场景:Linux中缺省的IO调度程序
完全公正的排队IO调度程序
- 公平体现在进程级
- 把IO请求放入特定的队列,每个进程有自己的一个队列
- 也会进行合并、排序
- 加入调度队列:轮询方式将各个队列的一组固定数目的请求填充调度队列
- 适合场景:确保磁盘IO带宽的公平分配
空操作的IO调度程序
只合并,基本和FIFO没什么区别
- 适合场景:闪存卡这种真正的随机访问设备,没有寻道的负担