内核为了处理来自IO层的请求,需要进行相应的优化,因为当请求很多时,且请求的块又都几种在一块,那么如果按照顺序处理这些请求无疑是很大的时间开销,所以,我们需要寻求方法来处理这种情况(当然,不只是这一种情况),这篇文章介绍的就是Linux中经典的IO调度程序--Linus电梯,这个是以Linux的发明者Linus自己的名字命名的。在2.4版的内核中,Linus电梯是默认的IO调度程序。虽然在后来的2.6版内核中它被另外两个调度程序所取代了,但是由于这个调度程序比后来的调度程序简单,而且它们执行的许多功能都相似,所以,它可以作为一个优秀的入门介绍程序。
首先,讲解下为什么这个调度程序被称作是电梯调度
大家都知道,我们在读磁盘上的数据时,首先肯定是磁头进行寻址,找到数据存储的位置(扇区)。而这个调度算法正是认为按着磁头方向移动的顺序调度请求是比较好的情况,当到达磁盘的末尾时,磁头再转换另一个方向移动到另一端,就像是生活中的电梯执行的方式,如下图所示:
Linus电梯能执行合并于排序预处理。当有新的请求加入队列时,它首先会检查其他每一个挂起的请求是否可以和新的请求合并。Linus电梯IO调度程序可以执行向前和向后合并,合并类型描述的是请求向前面还是向后面,这一点和已有请求连接。如果新的请求正好连在一个现存的请求前,那么就是向前合并;相反,如果一个请求连接在一个现存的请求之后,那么就是向后合并。鉴于文件的分布特点和IO操作执行方式具有典型性,所以向前合并要比向后合并少得多,但是Linus电梯还是会对两种合并类型都进行检查。
如果合并尝试失败,那么就需要寻找可能的插入点。如果找到,新的请求将被插入到该点;如果没有合适的位置,那么新的请求就被加入到队列的末尾。
总而言之,当一个请求加入到队列中时,有可能发生四种操作,它们依次是:
1> 如果队列中已经存在一个相邻磁盘扇区操作的请求,那么新的请求将会和这个已经存在的请求进行合并
2> 如果队列中存在一个驻留时间过长的请求,那么新的请求将被插入到队列尾部,已防止其他旧的请求存在饥饿现象
3> 如果队列中以扇区方法为序存在合适的插入位置,那么新的请求将被插入到该位置,保证队列中的请求是以被访问磁盘物理位置为序进行排列的
4> 如果队列中不存在合适的请求插入位置,请求将被插入到队列尾部