1、掌握fcfs、sstf、scan等磁碟排程演算法;
2、使用高階語言實現演算法,並比較不同演算法的優缺點。
磁碟排程在多道程式設計的計算機系統中,各個程序可能會不斷提出不同的對磁碟進行讀/寫操作的請求。由於有時候這些程序的傳送請求的速度比磁碟響應的還要快,因此我們有必要為每個磁碟裝置建立乙個等待佇列,常用的磁碟排程演算法有:先來先服務演算法(fcfs)、最短尋道時間優先演算法(sstf)、掃瞄演算法(scan)等。
一次磁碟讀寫操作的時間由尋找(尋道)時間、延遲時間和傳輸時間決定。在磁碟訪問時間的計算中,尋道時間與磁碟排程演算法相關,而延遲時間和傳輸時間都與磁碟旋轉速度相關,且為線性相關,所以在硬體上,轉速是磁碟效能的乙個非常重要的引數。總平均訪問時間ta可以表示為:ta = ts + tr + tt。
實驗內容:驗證fcfs、sstf、scan等磁碟排程演算法。
**(詳情見**注釋):
#include#include using namespace std;
#define inf 2147483647
class visit;
//程序請求類
class request
void reset();//復位,重新標記finish為未訪問
void achieve();//標記該請求已經完成
friend void fcfs(request** request, visit** visit, int num, int begin);
friend void sstf(request** request, visit** visit, int num, int begin);
friend void scan(request** request, visit** visit, int num, int begin, bool direction);
friend void show_visit(visit** visit, int num, int begin);
private:
int number;//磁軌號
bool finish;//是否完成訪問
};void request::reset()
void request::achieve()
//磁碟訪問類
//記錄訪問順序和移動距離
class visit
void reset();//復位。記錄清空
friend void fcfs(request** request, visit** visit, int num, int begin);
friend void sstf(request** request, visit** visit, int num, int begin);
friend void scan(request** request, visit** visit, int num, int begin, bool direction);
friend void show_visit(visit** visit, int num, int begin);
private:
int number;//被訪問的磁軌號
int distance;//移動距離
};void visit::reset()
//fcfs演算法
void fcfs(request** request, visit** visit, int num, int begin)
}//sstf演算法
void sstf(request** request, visit** visit, int num, int begin)
} //加入已訪問佇列
visit[i]->number = point->number;
visit[i]->distance = abs(begin - point->number);
//跟新磁頭位置,並標記已訪問
begin = point->number;
point->finish = true;
} return;
}//scan演算法
void scan(request** request, visit** visit, int num, int begin, bool direction)
if (min > request[i]->number)
}request *point;
for (int i = 0; i < num; i++)
//若當前請求距離更短且未被訪問過,則指向當前請求
if ((abs(point->number - begin) > abs(request[j]->number - begin)) && request[j]->finish == false)
} //加入已訪問佇列
visit[i]->number = point->number;
visit[i]->distance = abs(begin - point->number);
//跟新磁頭位置,並標記已訪問
begin = point->number;
point->finish = true;
//若到頭,則掉頭
if (direction == false && point->number == max)
if (direction == true && point->number == min)
}return;
}void show_option()
void show_visit(visit** visit, int num, int begin)
float ans = 0;
for (int i = 0; i < num; i++)
//保留兩位小數點後兩位
cout << " ——————————— " << endl;
cout << " 平均尋道長度:" << fixed << setprecision(2) << ans/num << endl;
cout << "—————————————" << endl;
}//request和visit復位
void reset(request** request, visit** visit, int num)
return;
}int main()
cout << "請輸入開始磁軌號:";
cin >> begin;
int flag;
while (true)
else if (flag == 2)
else if (flag == 3)
else if (flag == 4)
}return 0;
}
執行演示:
fcfs、sstf、scan三個磁碟排程演算法的難度是依次遞增的,理解它們的原理並不困難,但是要**實現卻有很多細節之處需要考慮。在這次實驗中,我建立了兩個類:一是程序請求類request,包含兩個成員變數,磁軌號int number、是否完成訪問bool finish;二是磁碟訪問類visit,包含兩個成員變數,被訪問的磁軌號int number、移動距離int distance,這個類的作用是記錄訪問順序和移動距離。
我想在這記錄一下scan演算法的實現思路,因為這可以說是三個演算法中最難的了。首先要找到最小和最大的磁軌號,這表示是邊界,如果我們掃瞄到邊界就需要轉頭了。接著對於visit的每乙個值,我們需要遍歷整個request,找出符合當前方向的、最近的乙個要求訪問的磁軌號。這裡我主要在sstf演算法基礎上加了乙個if語句,即如果是由裡向外且該請求磁軌號小於磁頭所在磁軌號或者由外向裡且該請求磁軌號大於磁頭所在磁軌號,那麼就跳過這乙個請求。在找到符合當前方向的、最近的乙個要求訪問的磁軌號後,我們除了要訪問該磁軌並作標記後,還要檢查是不是到了邊界,如果到了邊界還需要反轉掃瞄方向。scan的大致思路就是如此。
對於三者優缺點的比較。對於fcfs演算法,即先來先服務,是最直接、簡單、公平的,但是這顯然不夠合理。所以我們有了sstf演算法,即最短尋道優先,每次訪問離當前磁頭所在磁軌最近的要求訪問磁軌。書中的例子舉的其實不是很好,即沒有顯示出「飢餓」現象,也顯示得和scan演算法很相似,容易讓人誤解。言歸正傳,fcfs存在「飢餓」現象,即如果有新請求不斷出現在磁頭附近,這就導致一直在處理磁頭附近的請求,而遠處的請求會處於等待狀態。為了解決這個現象,我們又有了scan演算法,這個說白了就是來回掃瞄整個磁碟,固定乙個方向直到遇到邊界才回頭,很好簡單也很好理解但是卻解決了「飢餓」現象這個大問題。
作業系統實驗 磁碟排程
1,選擇一到三種磁碟排程演算法,模擬實現磁碟排程 2,能輸入當前磁頭的位置,磁頭移動方向,磁軌訪問請求序列等。3,計算磁頭移動的總磁軌數 4,能夠顯示磁碟排程結果 include include include disk.h using namespace std 磁碟 disk disk 新增訪問...
作業系統作業系統 實驗二 作業排程模擬程式
include include include typedef struct jcbjcb jcb jcbs 100 最多100個作業 int systime 0 bfsum,add,del intintarr,infin,intjob,sumjcb char t a t的預設值是a void in...
作業系統磁碟排程演算法
裝置的動態分配演算法與程序排程相似,也是基於一定的分配策略的。常用的分配策略有先請求先分配 優先順序高者先分配等策略。在多道程式系統中,低效率通常是由於磁碟類旋轉裝置使用不當造成的。作業系統中,對磁碟的訪問要求來自多方面,常常需要排隊。這時,對眾多的訪問要求按一定的次序響應,會直接影響磁碟的工作效率...