核心為了處理來自IO層的請求,需要進行相應的最佳化,因為當請求很多時,且請求的塊又都幾種在一塊,那麼如果按照順序處理這些請求無疑是很大的時間開銷,所以,我們需要尋求方法來處理這種情況(當然,不只是這一種情況),這篇文章介紹的就是Linux中經典的IO發送器--Linus電梯,這個是以Linux的發明者Linus自己的名字命名的。在2.4版的核心中,Linus電梯是預設的IO發送器。雖然在後來的2.6版核心中它被另外兩個發送器所取代了,但是由於這個發送器比後來的發送器簡單,而且它們執行的許多功能都相似,所以,它可以作為一個優秀的入門介紹程式。
首先,講解下為什麼這個發送器被稱作是電梯調度
大家都知道,我們在讀磁碟上的資料時,首先肯定是磁頭進行定址,找到資料存放區的位置(扇區)。而這個調度演算法正是認為按著磁頭方向移動的順序調度請求是比較好的情況,當到達磁碟的末尾時,磁頭再轉換另一個方向移動到另一端,就像是生活中的電梯執行的方式,如所示:
Linus電梯能執行合并於排序預先處理。當有新的請求排入佇列時,它首先會檢查其他每一個掛起的請求是否可以和新的請求合并。Linus電梯IO發送器可以執行向前和向後合并,合并類型描述的是請求向前面還是向後面,這一點和已有請求串連。如果新的請求正好連在一個現存的請求前,那麼就是向前合并;相反,如果一個請求串連在一個現存的請求之後,那麼就是向後合并。鑒於檔案的分布特點和IO操作執行方式具有典型性,所以向前合并要比向後合并少得多,但是Linus電梯還是會對兩種合并類型都進行檢查。
如果合并嘗試失敗,那麼就需要尋找可能的插入點。如果找到,新的請求將被插入到該點;如果沒有合適的位置,那麼新的請求就被加入到隊列的末尾。
總而言之,當一個請求加入到隊列中時,有可能發生四種操作,它們依次是:
1> 如果隊列中已經存在一個相鄰磁碟扇區操作的請求,那麼新的請求將會和這個已經存在的請求進行合并
2> 如果隊列中存在一個駐留時間過長的請求,那麼新的請求將被插入到隊列尾部,已防止其他舊的請求存在饑餓現象
3> 如果隊列中以扇區方法為序存在合適的插入位置,那麼新的請求將被插入到該位置,保證隊列中的請求是以被訪問磁碟物理位置為序進行排列的
4> 如果隊列中不存在合適的請求插入位置,請求將被插入到隊列尾部