操作系统实验之磁盘调度算法

一、实验内容

设计程序模拟先来先服务FCFS、最短寻道时间优先SSTF、SCAN和循环SCAN算法的工作过程。假设有n个磁道号所组成的磁道访问序列,给定开始磁道号m(SCAN、CSCAN中默认向磁道号增加的方向访问),分别利用不同的磁盘调度算法访问磁道序列,给出每一次访问的磁头移动距离,计算每种算法的平均寻道长度。

二、C++代码

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
const int MaxNumber=100;

void FCFS(int begin,int length,int TrackOrder[]){
    int  MoveDistance = 0;
    double  AverageDistance = 0;
    int i;
    cout<<"-------FCFS-------"<<endl;
    for (i = 1; i <= length; i++){
        MoveDistance = abs(TrackOrder[i] - TrackOrder[i-1]);//计算本次的寻道长度
        AverageDistance += MoveDistance;//累计寻道长度
        cout<<TrackOrder[i]<<"  "<<MoveDistance<<endl;//输出本次寻道长度
    }
    AverageDistance = AverageDistance / length;//计算平均寻道长度
    cout<<"平均寻道时间为:"<<AverageDistance<<endl;
    cout<<"---------------------"<<endl;
}                   

void SSTF(int begin,int length,int TrackOrder[]){
    int  MoveDistance;//寻道长度
    double  AverageDistance;//平均寻道时间
    int i,j,k,flag ,count = 0;//count用来计算目前已经完成寻道的磁道数量,flag用来存放开始寻道号所在的位置,
    //k值用来表示每一次查找的中心点,每次分别找到左右两边与k值相距最小且未被访问过的磁道
    sort(TrackOrder,TrackOrder + length);要将数组从小到大进行排序
    bool tag [length];//标记数组,标记某个磁道是否已经被访问过了
    for ( i = 0; i <= length; i++){
        tag[i] = false;//标记数组初始化
    }
    for ( i = 0; i <= length; i++){
        if (TrackOrder[i] == begin){
            flag = i;//找到开始寻道号所在的位置
        } 
    }
    k = flag;
    cout<<"-------SSTF-------"<<endl;
    while (count != length){//完成寻道的磁道数量不等于原始磁道序列长度
        for ( i = (k - 1 + length) % length; i >= 0; i--){//查找k左边距离k最小且未被访问的磁道,i = (k - 1 + length)的作用是若是k=0时,它的左边就从最后一个磁道开始递减查找
            if (i == flag || tag[i] == true)continue;
            break;
        }
        for ( j = (k + 1) % length; j < length; j++){//查找k右边距离k最小且未被访问的磁道,j = (k + 1) % length的作用是若是k=length时,它的右边边就从第一个开始递增查找
            if (j == flag || tag[j] == true)continue;
            break;
        }
        if (abs(TrackOrder[j] - TrackOrder[k]) < abs(TrackOrder[k] - TrackOrder[i])){
            MoveDistance = abs(TrackOrder[j] - TrackOrder[k]);//计算寻道时间
            AverageDistance += MoveDistance;//累计寻道时间
            ++count;//完成寻道的磁道数量+1
            tag[j] = true;//修改标记数组
            k = j;//下次以j为中心点,查找左右两边距离最小且未被访问的磁道
            cout<<TrackOrder[j]<<"  "<<MoveDistance<<endl;//输出本次寻道长度
        }else{
            MoveDistance = abs( TrackOrder[k] - TrackOrder[i]);//计算寻道时间
            AverageDistance += MoveDistance;//累计寻道时间
            ++count;//完成寻道的磁道数量+1
            tag[i] = true;//修改标记数组
            k = i;//下次以i为中心点,查找左右两边距离最小且未被访问的磁道
            cout<<TrackOrder[i]<<"  "<<MoveDistance<<endl;//输出
        }
    }
    AverageDistance = AverageDistance / length;//计算平均寻道长度
    cout<<"平均寻道时间为:"<<AverageDistance<<endl;
    cout<<"---------------------"<<endl;
}

void SCAN(int begin,int length,int TrackOrder[]){
    int  MoveDistance = 0;//寻道长度
    double  AverageDistance = 0;//平均寻道长度
    int i,temp,j;
    int flag = 0;//用flag来标记开始寻道号所在的位置
    //将数组进行排序
    sort(TrackOrder,TrackOrder + length);//将磁道号按大小排序
    for ( i = 0; i <= length; i++){//找到开始寻道号所在的位置
        if (TrackOrder[i] == begin){
            flag = i;
            break;
        }
    }
    cout<<"-------SCAN-------"<<endl;
    for (i = flag + 1;i <= length ;i++){//从开始寻道号所在位置的下一个开始直至访问到最大的磁道号
        MoveDistance = abs(TrackOrder[i] - TrackOrder[i-1]);//计算本次寻道长度
        AverageDistance += MoveDistance;//累计寻道长度
        cout<<TrackOrder[i]<<"  "<<MoveDistance<<endl;//输出本次寻道长度
    }
    for ( i = flag - 1 ;i >= 0 ;i--){
        if (i == flag - 1){
            //最大的磁道号减去小于开始寻道号的第一条磁道号
            MoveDistance = abs(TrackOrder[i] - TrackOrder[length]);//计算本次寻道长度
        }else{

            MoveDistance = abs(TrackOrder[i] - TrackOrder[i+1]);//计算本次寻道长度
        }
        cout<<TrackOrder[i]<<"  "<<MoveDistance<<endl;//输出本次寻道长度
        AverageDistance += MoveDistance;//累计寻道长度
    }
    AverageDistance = AverageDistance / length;//计算并输出平均寻道时间
    cout<<"平均寻道时间为:"<<AverageDistance<<endl;
    cout<<"---------------------"<<endl;
}

void CSCAN(int begin,int length,int TrackOrder[]){
    int  MoveDistance = 0;//寻道长度
    double  AverageDistance = 0;//平均寻道长度
    int i,temp,j;
    int flag = 0;//用flag来标记开始寻道号所在的位置
    //要将数组从小到大进行排序
    sort(TrackOrder,TrackOrder + length);
    for ( i = 0; i <= length; i++){
        if (TrackOrder[i] == begin){//找到开始寻道号所在的位置
            flag = i;
            break;
        }
    }
    cout<<"-------CSCAN-------"<<endl;
    for (i = flag + 1;i != flag; i++){
        temp = i % (length+1);//循环查找
        MoveDistance = abs(TrackOrder[temp] - TrackOrder[i-1]);//计算本次寻道长度
        AverageDistance += MoveDistance;//累计寻道长度
        cout<<TrackOrder[temp]<<"  "<<MoveDistance<<endl;//输出本次寻道长度
        i = temp;
    }
    AverageDistance = AverageDistance / length;//计算并输出平均寻道时间
    cout<<"平均寻道时间为:"<<AverageDistance<<endl;
    cout<<"---------------------"<<endl;
}

int main(int argc, char* argv[]){
    int TrackOrder[MaxNumber];//磁道序列
    //0 55 58 39 18 90 160 150 38 184
    //= {0,55,58,39,18,90,160,150,38,184};
    // int length = 10;
    // int begin = 100;
    int length;//磁道序列的原始长度
    int begin;//开始寻道号
    cout<<"请输入磁道个数:";
    cin>>length;
    cout<<"请输入磁道序列:";
    for (int i = 1; i <= length; i++){
        cin>>TrackOrder[i];
    }
    cout<<"请输入开始磁道号:";
    cin>>begin;
    TrackOrder[0] = begin;//把开始寻道号加入磁道序列
    int i;
    while (1){
        cout<<"输入你要执行的操作:"<<endl;
        cout<<"算法选择:1-FCFS,2-SSTF,3-SCAN,4-循环SCAN,5-退出:";
        cin>>i;
        if (i == 1){
            FCFS(begin,length,TrackOrder);
        }else if (i == 2){
            SSTF(begin,length,TrackOrder);
        }else if (i == 3){
            SCAN(begin,length,TrackOrder);
        }else if (i == 4){
            CSCAN(begin,length,TrackOrder);
        }
        else{
            break;
        }
    } 
	return 0;
}
  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值