磁盘调度算法(操作系统实验 C++)

磁盘调度算法

1.实验目的

通过这次实验,加深对磁盘调度算法的理解,进一步掌握先来先服务FCFS、最短寻道时间优先SSTF、SCAN和循环SCAN算法的实现方法。

2.实验内容

问题描述:
设计程序模拟先来先服务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)输出:每种算法的平均寻道长度。
实现提示:
用C++语言实现提示:
1)程序中变量定义参考(根据需要可添加)如下:
const int MaxNumber=100;
int TrackOrder[MaxNumber];
int MoveDistance[MaxNumber];
double AverageDistance;
bool direction;
2)页面置换的实现过程如下:
变量初始化;

  • 接收用户输入磁道个数n和磁盘访问序列,选择算法1-FCFS,2-SSTF,3-SCAN,4-循环SCAN,输入开始磁盘号m和磁头移动方向;

  • 根据用户选择的算法进行磁道访问,输出磁盘调度算法的模拟过程;

  • 计算选择每次移动的磁头移动距离和算法的平均寻道长度;

  • 输出选择算法的平均寻道长度。

实验要求:
1)上机前认真复习磁盘调度算法,熟悉FCFS、SSTF、SCAN和循环SCAN算法的过程;
2)上机时独立编程、调试程序;
3)根据具体实验要求,完成好实验报告(包括实验的目的、内容、要求、源 程序、实例运行结果截图、发现的问题以及解决方法)。

3.程序主要构成部分及其算法说明

1.FCFS(先来先服务算法)
先对队列进行初始化,计算开始磁道号和队列中的第一个磁道号的距离,然后按照输入顺序依次访问磁道,计算移动距离,最后计算平均寻道长度。

void FCFS(){
    initial();  
 	 cout<<"FCFS"<<endl;
   
MoveDistance[0] = abs(TrackOrder[0]-StartTrack);
VisitOrder[i] = TrackOrder[i];
SumDistance = MoveDistance[0];

    for (int i=1;i<TrackNum;i++){
        MoveDistance[i] = abs(TrackOrder[i]-TrackOrder[i-1]);、
		 VisitOrder[i] = TrackOrder[i];
        SumDistance += MoveDistance[i];
    }
    AverageDistance = SumDistance*1.0/TrackNum;
    output();
}
  1. SSTF(最短寻找时间优先)
    先对队列进行初始化,然后用嵌套for循环计算,内部的第一个for循环先用来计算序列中所有磁道和第一个磁道(赋值给CurrentTrack)的距离存放在数组distance中,然后用第二个for循环找到距离最近的序列号pointMin,计算距离和记录位置后将pointMin赋值给CurrentTrack,然后外部for循环这个过程,对已经访问过的磁道给其一个较大的值,防止其再次被访问。
void SSTF(){
    initial();
    cout<<"SSTF"<<endl;
    int CurrentTrack = StartTrack;
    int i,j,pointMin;
    int distance[MaxNumber];
 
    for (i = 0;i<TrackNum;i++){
        for (j = 0;j<TrackNum;j++){
            if (!isVisit[j])
                distance[j] = abs(TrackOrder[j]-CurrentTrack);
            else
                distance[j] = 1000000;
        }
        pointMin = 0;
        for (j = 0;j<TrackNum;j++){
            if (distance[pointMin] > distance[j])
                pointMin = j;   
        }
        VisitOrder[i] = TrackOrder[pointMin];  
        MoveDistance[i] = abs(TrackOrder[pointMin]-CurrentTrack);  /
        SumDistance += MoveDistance[i];   
        CurrentTrack = TrackOrder[pointMin];  
        isVisit[pointMin] = true;  
    }
    AverageDistance = SumDistance*1.0/(TrackNum);
    output();
}

3.SCAN(扫描算法)
先对序列初始化,然后输入磁头移动的方向,建立新数组用来存放排序后的磁道序列。使用一个冒泡循环得出从小到大的磁道号序列。设置point,让其指向找既在当前磁道之外,又是距离最近的磁道号。如果选择增加方向,则先从point开始,第一个for循环依次遍历磁道号比point大的磁道,计算移动距离和存放位置,再将 下一个磁道号赋值给currentTrack进行下一次计算。第二个for循环从磁道号比point小的磁道开始进行相同的计算。如果选择减少的方向,则与增加方向相反。

void SCAN(){
    initial();
cout<<"SCAN"<<endl;
int i,j,temp;
    int SortTrackOrder[MaxNumber];
    cout<<"选择磁头移动的方向,1-增加,2-减少: "<<endl;
    cin>>direction;
   
    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 == 1){  
        cout<<"向磁道增加的方向访问"<<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 == 2){  
        cout<<"向磁道减少的方向访问"<<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++){
        SumDistance += MoveDistance[i];
    }
    AverageDistance = (SumDistance*1.0)/TrackNum;
    output();
}
  1. CSCAN(循环扫描SCAN算法)
    先对序列初始化,然后输入磁头移动的方向,建立新数组用来存放排序后的磁道序列。使用一个冒泡循环得出从小到大的磁道号序列。设置point,让其指向找既在当前磁道之外,又是距离最近的磁道号。如果选择增加方向,则先从point开始,第一个for循环依次遍历磁道号比point大的磁道,计算移动距离和存放位置,再将下一个磁道号赋值给currentTrack进行下一次计算。第二个for循环从最小的磁道号开始进行相同的计算。如果选择减少的方向,先从比point小一号的磁道号开始依次按磁道号减少遍历,再从磁道号最大的序列开始按磁道号减少计算。
	initial();
    cout<<"CSCAN"<<endl;
    cout<<"选择磁头移动的方向,1-增加,2-减少: "<<endl;
    cin>>direction;
 
    int SortTrackOrder[MaxNumber];
    int i,j,temp;
    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 == 1){  
        cout<<"向磁道增加的方向访问"<<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 == 2){ 
        cout<<"向磁道减少的方向访问"<<endl;
        for (i = point-1;i>=0;i--){
            VisitOrder[count] = SortTrackOrder[i];
            MoveDistance[count] = abs(VisitOrder[count]-currentTrack);
            currentTrack = VisitOrder[count];
            count++;
        }
        for (i = TrackNum-1;i>point-1;i--){
            VisitOrder[count] = SortTrackOrder[i];
            MoveDistance[count] = abs(VisitOrder[count]-currentTrack);
            currentTrack = VisitOrder[count];
            count++;
        }
    }
    for (i = 0;i<TrackNum;i++){
        SumDistance += MoveDistance[i];
    }
    AverageDistance = (SumDistance*1.0)/TrackNum;
    output();
}

4.运行结果

1.程序读取data中的数据并输出,输入1执行FCFS算法。输出磁盘调度算法的模拟过程,每次移动的磁头移动距离和算法的平均寻道长度。
在这里插入图片描述

2.输入2执行SSTF算法。输出磁盘调度算法的模拟过程,每次移动的磁头移动距离和算法的平均寻道长度
在这里插入图片描述

3.输入3执行SCAN算法。输入1选择磁头移动方向为增加方向,输入2选择磁头移动方向为减少方向;输出磁盘调度算法的模拟过程,每次移动的磁头移动距离和算法的平均寻道长度
在这里插入图片描述

在这里插入图片描述

4.输入4执行CSCAN算法。输入1选择磁头移动方向为增加方向,输入2选择磁头移动方向为减少方向;输出磁盘调度算法的模拟过程,每次移动的磁头移动距离和算法的平均寻道长度

在这里插入图片描述
在这里插入图片描述

5.程序源码

#include <iostream>
#include <fstream>
#include <iomanip>
#include <cmath>
#include <stdlib.h>
using namespace std;
 
#define MaxNumber 100
int TrackOrder[MaxNumber];//初始磁道序列
int MoveDistance[MaxNumber];//磁头移动距离(磁道数)
double AverageDistance;//磁头平均移动距离
int direction;//选择磁头方向 
int TrackNum;//磁道数
int StartTrack;//开始磁道号m 
int VisitOrder[MaxNumber];//访问磁道序列
bool isVisit[MaxNumber];//标记是否被访问过
int SumDistance;//磁头移动的总距离
int choose;

void input();//输入起始磁道号、磁道顺序
void initial();
void output();
void FCFS();//先来先服务,先进先出
void SSTF();//最短寻道时间优先
void SCAN();//扫描,从开始磁道沿选择方向扫描,直到没有要访问的磁道在沿反方向扫描
void CSCAN();//循环扫描,自开始磁道始终沿一个方向扫描,直到没有要访问的磁道再从最里圈或最外圈扫描
void chooseAlgorithm();
 
int main(){
    input();
    chooseAlgorithm();
    return 0;
}
 
void input(){
    ifstream readData;
	readData.open("data.txt");
	readData>>TrackNum;  //磁道个数
	for (int i=0;i<TrackNum;i++)
	{
		readData>>TrackOrder[i];   //磁道访问序列
	}
	readData>>StartTrack;  //开始磁道号
	cout<<"磁道个数 = "<<TrackNum<<endl;
	cout<<"磁道访问序列:";
	for (int i=0;i<TrackNum;i++)
	{
		cout<<TrackOrder[i]<<" ";
	}
	cout<<endl;
	cout<<"开始磁道号m= "<<StartTrack<<endl;
	cout<<"------------------------------------"<<endl;
}
void initial(){
    for (int i=0;i<TrackNum;i++){
        MoveDistance[i] = 0;
        VisitOrder[i] = TrackOrder[i];
        isVisit[i] = false;
    }
    SumDistance = 0;
    AverageDistance = 0;
}

void output(){
    cout<<"从"<<StartTrack<<"号磁道开始"<<endl;
    cout<<"被访问的下一个磁道号"<<"\t"<<"移动距离"<<"\t"<<endl;
    for (int i=0;i<TrackNum;i++){
        cout<<VisitOrder[i]<<"\t\t\t"<<MoveDistance[i]<<"\t"<<endl;
    }
    cout<<"平均寻道长度: "<<setprecision(4)<<AverageDistance<<endl;
    cout<<endl;
}
 
//先来先服务,先进先出
void FCFS(){
    cout<<endl;
    cout<<"FCFS"<<endl;
    initial();
 
    //按照输入顺序依次访问磁道
    MoveDistance[0] = abs(TrackOrder[0]-StartTrack);
    SumDistance = MoveDistance[0];
    VisitOrder[0] = TrackOrder[0];
 
    for (int i=1;i<TrackNum;i++){
        MoveDistance[i] = abs(TrackOrder[i]-TrackOrder[i-1]);
        SumDistance += MoveDistance[i];
        VisitOrder[i] = TrackOrder[i];
    }
 
    AverageDistance = SumDistance*1.0/TrackNum;
    output();
}
 
//最短寻道时间优先
void SSTF(){
    cout<<endl;
    cout<<"SSTF"<<endl;
    initial();
    int CurrentTrack = StartTrack;
    int i,j,pointMin;
    int distance[MaxNumber];
 
    for (i = 0;i<TrackNum;i++){
        for (j = 0;j<TrackNum;j++){
            if (!isVisit[j])
                distance[j] = abs(TrackOrder[j]-CurrentTrack);
            else
                distance[j] = 10000;  //表示无穷远,即访问过的磁道就不再访问
        }
        pointMin = 0;
        for (j = 0;j<TrackNum;j++){
            if (distance[pointMin] > distance[j])
                pointMin = j;   //指向最小的位置
        }
        VisitOrder[i] = TrackOrder[pointMin];  //给访问序列赋值
        MoveDistance[i] = abs(TrackOrder[pointMin]-CurrentTrack);  //计算每次的移动距离
        SumDistance += MoveDistance[i];   //累计移动距离
        CurrentTrack = TrackOrder[pointMin];   //改变当前的磁道号
        isVisit[pointMin] = true;  //将当前的磁道号设置为已访问
    }
    AverageDistance = SumDistance*1.0/(TrackNum);
    output();
}
 
//扫描,从开始磁道沿选择方向扫描,直到没有要访问的磁道在沿反方向扫描
void SCAN(){
    cout<<endl;
    cout<<"SCAN"<<endl;
    cout<<"选择磁头移动的方向,1-增加,2-减少: "<<endl;
    cin>>direction;
    initial();
 
    int i,j,temp;
    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 == 1){  //向磁道增加的方向访问
        cout<<"向磁道增加的方向访问"<<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 == 2){  //向磁道减少的方向访问
        cout<<"向磁道减少的方向访问"<<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++){
        SumDistance += MoveDistance[i];
    }
    AverageDistance = (SumDistance*1.0)/TrackNum;
    output();
}
 
//循环扫描,自开始磁道始终沿一个方向扫描,直到没有要访问的磁道再从最里圈或最外圈扫描
void CSCAN(){

	initial();
    cout<<"CSCAN"<<endl;
    cout<<"选择磁头移动的方向,1-增加,2-减少: "<<endl;
    cin>>direction;
 
    
    int SortTrackOrder[MaxNumber];
    int i,j,temp;
    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 == 1){  
        cout<<"向磁道增加的方向访问"<<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 == 2){//向磁道减少的方向访问
        cout<<"向磁道减少的方向访问"<<endl;
        for (i = point-1;i>=0;i--){
            VisitOrder[count] = SortTrackOrder[i];
            MoveDistance[count] = abs(VisitOrder[count]-currentTrack);
            currentTrack = VisitOrder[count];
            count++;
        }
        for (i = TrackNum-1;i>point-1;i--){
            VisitOrder[count] = SortTrackOrder[i];
            MoveDistance[count] = abs(VisitOrder[count]-currentTrack);
            currentTrack = VisitOrder[count];
            count++;
        }
    }
 
    for (i = 0;i<TrackNum;i++){
        SumDistance += MoveDistance[i];
    }
    AverageDistance = (SumDistance*1.0)/TrackNum;
    output();
}


void chooseAlgorithm()
{
	cout<<"请选择算法“1-FCFS,2-SSTF,3-SCAN,4-循环SCAN ,0-退出”"<<endl;
	cin>>choose;
	if (choose==1)
	{
		FCFS();
		chooseAlgorithm();
	}
		else if(choose==2)
		{
			SSTF();
			chooseAlgorithm();
		}
		else if(choose==3){
            SCAN();
        	chooseAlgorithm();
		}
		else if(choose==4){
            CSCAN();
            chooseAlgorithm();
		}
		else if(choose==0){
          exit(0);
		}
	else
	{
		cout<<"请输入正确的选择“1-FCFS,2-SSTF,3-SCAN,4-循环SCAN ,0-退出”"<<endl;
		chooseAlgorithm();  
	}
}

输入数据格式

10
78 30 9 15 102 140 156 54 45 125
100

  • 10
    点赞
  • 88
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
$$完整代码+22页实验报告$$。#大车埋土#进程调度算法包括先来先服务调度算法 FCFS、最短作业时间优先 SJF(抢占式 和非抢占式)、最高响应比调度 HRN 算法 4 种。(每个人必须做非抢占式 SJF, 然后在后面的三种中任选一种,即每个人必须做 2 种调度算法模拟。) [2]. 衡量算法性能的参数 计算进程的平均周转时间和平均带权周转时间。 3. 实验内容 (1)编程实现本实验的程序,要求: [1]. 建立进程的进程控制块,进程控制块至少包括: a) 进程名称; b) 进程需要执行时间; c) 进入就绪队列时间; d) 进程执行开始时间 e) 进程执行结束时间 [2]. 编程实现调度算法。 [3]. 进程及相关信息的输入。这些信息可以直接从键盘上输入,也可以从文件读 取。 [4]. 时间片与时间流逝的模拟。本实验需要对算法的执行计时,程序应该提供计 算时间的方法。一种最简单的方法是使用键盘,比如每敲一次空格代表一个 2 时间片的流逝。另一种方法是使用系统时钟。 [5]. 一组进程序列执行完毕,打印出结果信息。程序需要计算出每个进程的开始 执行时间、结束时间、周转时间和带权周转时间,并为整个进程序列计算平 均周转时间和平均带权周转时间程序将计算结果按一定的格式显示在计算 机屏幕上或输出到文件中。打印出进程调度顺序图。 [6]. 实现数据在磁盘文件上的存取功能。 (2)对下列就绪进程序列分别使用上面的几种算法进行调度,计算每种算 法下的平均周转时间和平均带权周转时间。 进程 到达时间 要求执行时间 0 0 1 1 1 35 2 2 10 3 3 5 4 6 9 5 7 21 6 9 35 7 11 23 8 12 42 9 13 1 10 14 7 11 20 5 12 23 3 13 24 22 14 25 31 15 26 1

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值