实验六
【实验题目】:磁盘调度算法
【实验目的】
通过这次实验,加深对磁盘调度算法的理解,进一步掌握先来先服务FCFS,最短寻道时间优先SSTF,SCAN和循环SCAN算法的实现方法。
【实验内容及要求】
算法思路:
FCFS:算法思想非常简单,就是不论初始磁头在什么位置,都是按照服务队列的先后顺序依次处理进程,可以类比队列的先进先出。优点是进程处理起来非常简单,但缺点显而易见,就是平均寻道长度会很长。
SSTF:最短寻道时间算法,算法本质是贪心,已知磁头的初始位置,则最先被处理就是距离磁头位置最近的进程,处理完成后再处理距离当前磁道最近的进程,直到所有的进程被处理。该算法的优点是平均寻道长度会大大减少,缺点是距离初始磁头较远的服务长期得不到处理,产生“饥饿”现象。具体的思路是:通过循环寻找与初始磁头最近的进程,将进程处理,然后将该进程标记,将初始磁头移动到该进程所在的磁道。然后依次类推,已经标记的进程不再参与,直到所有的进程都被标记,磁盘调度完成。
SCAN:磁头仅沿一个方向进行扫描,在扫描途中完成所有没有完成的请求,直到磁头到达磁盘在这个方向上的最后一个磁道或者这个方向上最后一个请求所在的磁道。利用数组存储进程和磁道编号,依据给定的初始磁头,先找到初始磁头在哪两个进程之间,然后向内扫描。当磁头扫描到磁盘最内层即磁道0且进程还没有全部被处理,磁头开始向外扫描,直到所有的进程都完成。
CSCAN:在磁盘扫描算法的基础上改变磁头的扫描路径:扫描到最内层之后从最外层向内继续扫描,即扫描方向一致。该算法的思路与扫描算法基本一致,也使用二维数组进行进程编号和进程所在磁道号的存储,算法的不同之处在于当磁头扫描到磁盘的最内层时,磁头跳转到磁盘最外层重新向内扫描,这样就可以有效的避免将已经扫描过的磁道重新扫描一次,降低了平均寻到距离。
假设磁盘访问序列:98,183,37,122,14,124,65,67。读写头起始位置:53
问题描述:
设计程序模拟先来先服务FCFS,最短寻道时间优先SSTF,SCAN和循环SCAN算法的工作过程。假设有n个磁道号所组成的磁道访问序列,给定开始磁道号m和磁头移动的方向(正向或者反向),分别利用不同的磁盘调度算法访问磁道序列,给出每一次访问的磁头移动距离,计算每种算法的平均寻道长度。
程序要求如下:
1)利用先来先服务FCFS,最短寻道时间优先SSTF,SCAN和循环SCAN算法模拟磁道访问过程。
2)模拟四种算法的磁道访问过程,给出每个磁道访问的磁头移动距离。
3)输入:磁道个数n和磁道访问序列,开始磁道号m和磁头移动方向(对SCAN和循环SCAN算法有效),算法选择1-FCFS,2-SSTF,3-SCAN,4-循环SCAN。
4)输出:四种算法的每次磁头移动寻道长度和平均寻道长度。
【流程图】
【实验结果】
核心代码:
可读文本文件:
实验结果截图:
先来先服务算法:
最短寻道时间优先算法:
SCAN算法:
循环扫描(CSCAN)算法:
【源代码】
#include <iostream>
#include <fstream>
#include <iomanip>
#include <cmath>
#include <stdlib.h>
using namespace std;
#define MaxNumber 100
int TrackNum;//磁道数
int StartTrack;//开始磁道
int TrackOrder[MaxNumber];//初始磁道序列
int VisitOrder[MaxNumber];//访问磁道序列
bool Visited[MaxNumber];//标记是否被访问过
int MoveDistance[MaxNumber];//磁头移动距离(磁道数)
int Sum_Distance;//磁头移动的总距离
double AverageDistance;//磁头平均移动距离
bool direction;//选择磁头向内或向外方向
int choose;
void Enter(); //输入起始磁道号、磁道顺序
void initial();
void display();
void FCFS();//先来先服务,先进先出
void SSTF();//最短寻道时间优先
void SCAN();//扫描,从开始磁道沿选择方向扫描,直到没有要访问的磁道在沿反方向扫描
void CSCAN();//循环扫描,自开始磁道始终沿一个方向扫描,直到没有要访问的磁道再从最里圈或最外圈扫描
void choose_Algorithm();
int main(){
Enter();
choose_Algorithm();
return 0;
}
void Enter(){
int i;
ifstream readData;
readData.open("datainput.txt");
readData>>TrackNum; //磁道个数
for (i=0;i<TrackNum;i++)
{
readData>>TrackOrder[i]; //磁道访问序列
}
readData>>StartTrack; //开始磁道号
cout<<"读取信息如下:"<<endl;
cout<<"磁道个数TrackNum = "<<TrackNum<<endl;
cout<<"磁道访问序列:";
for (i=0;i<TrackNum;i++)
{
cout<<TrackOrder[i]<<" ";
}
cout<<endl;
cout<<"开始磁道号StartTrack = "<<StartTrack<<endl;
cout<<"------------------------------------"<<endl;
}
void initial(){
for (int i=0;i<TrackNum;i++){
MoveDistance[i] = 0;
VisitOrder[i] = TrackOrder[i];
Visited[i] = false;
}
Sum_Distance = 0;
AverageDistance = 0;
}
void display(){
int i;
cout<<"Start: "<<StartTrack<<endl;
cout<<"Next"<<"\t"<<"Distance"<<"\t"<<endl;
for (i=0;i<TrackNum;i++){
cout<<VisitOrder[i]<<"\t"<<MoveDistance[i]<<"\t"<<endl;
}
cout<<"AverageDistance: "<<setprecision(4)<<AverageDistance<<endl;
}
//先来先服务,先进先出
void FCFS(){
cout<<endl;
cout<<"FCFS"<<endl;
initial();
//按照输入顺序依次访问磁道
MoveDistance[0] = abs(TrackOrder[0]-StartTrack);
Sum_Distance = MoveDistance[0];
VisitOrder[0] = TrackOrder[0];
for (int i=1;i<TrackNum;i++){
MoveDistance[i] = abs(TrackOrder[i]-TrackOrder[i-1]);
Sum_Distance += MoveDistance[i];
VisitOrder[i] = TrackOrder[i];
}
AverageDistance = Sum_Distance*1.0/TrackNum;
display();
}
//最短寻道时间优先
void SSTF(){
cout<<endl;
cout<<"SSTF"<<endl;
initial();
int CurrentTrack = StartTrack;
int i,j,pointMin;
int disTemp[MaxNumber];
for (i = 0;i<TrackNum;i++){
for (j = 0;j<TrackNum;j++){
if (!Visited[j])
disTemp[j] = abs(TrackOrder[j]-CurrentTrack);
else
disTemp[j] = 10000; //表示无穷远,即访问过的磁道就不再访问
}
pointMin = 0;
for (j = 0;j<TrackNum;j++){
if (disTemp[pointMin] > disTemp[j])
pointMin = j; //指向最小的位置
}
VisitOrder[i] = TrackOrder[pointMin]; //给访问序列赋值
MoveDistance[i] = abs(TrackOrder[pointMin]-CurrentTrack); //计算每次的移动距离
Sum_Distance += MoveDistance[i]; //累计移动距离
CurrentTrack = TrackOrder[pointMin]; //改变当前的磁道号
Visited[pointMin] = true; //将当前的磁道号设置为已访问
}
AverageDistance = Sum_Distance*1.0/(TrackNum);
display();
}
//扫描,从开始磁道沿选择方向扫描,直到没有要访问的磁道在沿反方向扫描
void SCAN(){
cout<<endl;
cout<<"SCAN"<<endl;
cout<<"Choose direction,0-add,1-reduce: "<<endl;
cin>>direction;
initial();
int i,j,temp,tempIndex;
int SortTrackOrder[MaxNumber];
for (i = 0;i<TrackNum;i++){//初始化
SortTrackOrder[i] = TrackOrder[i];
}
//冒泡排序
for (i = 0;i<TrackNum;i++){
for (j = i;j<TrackNum;j++){
if (SortTrackOrder[i]>=SortTrackOrder[j]){
temp = SortTrackOrder[i];
SortTrackOrder[i] = SortTrackOrder[j];
SortTrackOrder[j] = temp;
}
}
}
//找到既在当前磁道之外,又是距离最近的磁道号
int point = 0;
while(StartTrack>=SortTrackOrder[point]){
point++;
}
int count = 0;
int currentTrack = StartTrack;
if (direction == 0){ //向磁道增加的方向访问
cout<<"Add"<<endl;
for (i = point;i<TrackNum;i++){
VisitOrder[count] = SortTrackOrder[i];
MoveDistance[count] = abs(VisitOrder[count]-currentTrack);
currentTrack = VisitOrder[count];
count++;
}
for (i = point - 1;i>=0;i--){
VisitOrder[count] = SortTrackOrder[i];
MoveDistance[count] = abs(VisitOrder[count]-currentTrack);
currentTrack = VisitOrder[count];
count++;
}
}
else if (direction == 1){ //向磁道减少的方向访问
cout<<"Reduce"<<endl;
for (i = point - 1;i>=0;i--){
VisitOrder[count] = SortTrackOrder[i];
MoveDistance[count] = abs(VisitOrder[count]-currentTrack);
currentTrack = VisitOrder[count];
count++;
}
for (i = point;i<TrackNum;i++){
VisitOrder[count] = SortTrackOrder[i];
MoveDistance[count] = abs(VisitOrder[count]-currentTrack);
currentTrack = VisitOrder[count];
count++;
}
}
for (i = 0;i<TrackNum;i++){
Sum_Distance += MoveDistance[i];
}
AverageDistance = (Sum_Distance*1.0)/TrackNum;
display();
}
//循环扫描,自开始磁道始终沿一个方向扫描,直到没有要访问的磁道再从最里圈或最外圈扫描
void CSCAN(){
cout<<endl;
cout<<"CSCAN"<<endl;
cout<<"Choose direction,0-add,1-reduce: "<<endl;
cin>>direction;
initial();
int SortTrackOrder[MaxNumber];
int i,j,temp,tempIndex;
for (i = 0;i<TrackNum;i++){
SortTrackOrder[i] = TrackOrder[i];
}
//冒泡排序
for (i = TrackNum - 1;i>0;i--){
for (j = 0;j<i;j++){
if (SortTrackOrder[j]>=SortTrackOrder[j+1]){
temp = SortTrackOrder[j];
SortTrackOrder[j] = SortTrackOrder[j+1];
SortTrackOrder[j+1] = temp;
}
}
}
//找到既在当前磁道之外,又是距离最近的磁道号
int point = 0;
while(StartTrack>=SortTrackOrder[point]){
point++;
}
int count = 0;
int currentTrack = StartTrack;
if (direction == 0){ //向磁道增加的方向访问
cout<<"Add"<<endl;
for (i = point;i<TrackNum;i++){
VisitOrder[count] = SortTrackOrder[i];
MoveDistance[count] = abs(VisitOrder[count]-currentTrack);
currentTrack = VisitOrder[count];
count++;
}
for (i =0;i<point;i++){
VisitOrder[count] = SortTrackOrder[i];
MoveDistance[count] = abs(VisitOrder[count]-currentTrack);
currentTrack = VisitOrder[count];
count++;
}
}
else if (direction == 1){//向磁道减少的方向访问
cout<<"Reduce"<<endl;
for (i = 0;i<point;i++){
VisitOrder[count] = SortTrackOrder[i];
MoveDistance[count] = abs(VisitOrder[count]-currentTrack);
currentTrack = VisitOrder[count];
count++;
}
for (i = point;i<TrackNum;i++){
VisitOrder[count] = SortTrackOrder[i];
MoveDistance[count] = abs(VisitOrder[count]-currentTrack);
currentTrack = VisitOrder[count];
count++;
}
}
for (i = 0;i<TrackNum;i++){
Sum_Distance += MoveDistance[i];
}
AverageDistance = (Sum_Distance*1.0)/TrackNum;
display();
}
void choose_Algorithm()
{
cout<<"请选择算法“1-先来先服务算法,2-最短寻道时间优先算法,3-SCAN算法,4-循环扫描(CSCAN)算法:,0-退出”"<<endl;
cout<<endl;
cin>>choose;
cout<<endl;
if (choose==1)
{
FCFS();
choose_Algorithm();
}
else if(choose==2)
{
SSTF();
choose_Algorithm();
}
else if(choose==3){
SCAN();
choose_Algorithm();
}
else if(choose==4){
CSCAN();
choose_Algorithm();
}
else if(choose==0){
exit(0);
}
else
{
cout<<"请输入正确的选择“1-先来先服务算法,2-最短寻道时间优先算法,3-SCAN算法,4-循环扫描(CSCAN)算法:,0-退出”"<<endl;
cout<<"------------------------------------------------------"<<endl;
choose_Algorithm(); //递归
}
}
参考网址:https://blog.csdn.net/qq_40695551/article/details/85060438