一、实验要求
1.基础知识
掌握磁盘调度的相关内容,对磁盘结构及调度算法有深入的理解。
2.具体要求
(1)选择2~3中磁盘调度算法(先来先服务、最短寻道时间优先、电梯算法)
(2)输入:当前磁头位置、磁头移动方向、磁道访问请求序列
(3)输出:磁头依次访问的磁道号顺序,计算磁头移动的总磁道数
二、运行截图
三、代码结构
1.项目结构
2.文件说明
ApplicationEntrance:程序入口
InputAction:输入有关的操作
OutputAction:输出有关的操作
Algorithm:三个调度策略
Constants:常量文件
3.本次程序从文件input.txt中读入初始数据
每行分别是:当前磁头位置,磁头移动方向,请求序列
四、完整源代码
ApplicationEntrance:
/*
* @author W-nut
*/
#include <iostream>
#include "Constants.h"
#include "InputAction.h"
#include "OutputAction.h"
#include "Algorithm.h"
using namespace std;
int main(int argc, char** argv)
{
InputInit();
while (true)
{
OutputMenu();
int selection = InputSelection();
switch (selection)
{
case FCFS: {
FirstComeFirstServe();
OutputVisitOrder();
cout << endl << endl;
break;
}
case SSTF:{
ShortestSearchTimeFirst();
OutputVisitOrder();
cout << endl << endl;
break;
}
case SCAN: {
Scan();
OutputVisitOrder();
cout << endl << endl;
break;
}
case SHOW: {
OutputInit();
cout << endl << endl;
break;
}
case EXIT: {
cout << "程序退出!" << endl;
exit(0);
}
}
}
return 0;
}
Algorithm:
/*
* @author W-nut
*/
#pragma once
#include <iostream>
#include <vector>
#include<algorithm>
#include "Constants.h"
using namespace std;
//定义最短距离
bool MinimumDistance(Request_Num e1, Request_Num e2)
{
return e1.distance < e2.distance;
}
//先来先服务
void FirstComeFirstServe()
{
if (!visit_order.empty())
visit_order.clear();
if (total_instance != 0)
total_instance = 0;
visit_order.push_back(start_position);
for (int request : request_order)
{
total_instance += abs(request - visit_order.back());
visit_order.push_back(request);
current_position = request;
}
}
//最短寻道时间优先
void ShortestSearchTimeFirst()
{
if (!visit_order.empty())
visit_order.clear();
if (total_instance != 0)
total_instance = 0;
if (!Request_Order.empty())
Request_Order.clear();
visit_order.push_back(start_position);
current_position = start_position;
for (int request : request_order)
{
Request_Num e;
e.request_num = request;
e.distance = abs(request - current_position);
Request_Order.push_back(e);
}
//有几个请求号循环几次
int total_request = request_order.size();
for (int i = 0; i < total_request; ++i)
{
vector<Request_Num>::iterator min = min_element(Request_Order.begin(), Request_Order.end(), MinimumDistance);
current_position = min->request_num;
total_instance += abs(current_position - visit_order.back());
visit_order.push_back(current_position);
//删除请求过的元素
Request_Order.erase(min);
//更新距离
for (Request_Num & ru : Request_Order)
{
ru.distance= abs(ru.request_num - current_position);
}
}
}
//电梯扫描
void Scan()
{
if (!visit_order.empty())
visit_order.clear();
if (total_instance != 0)
total_instance = 0;
visit_order.push_back(start_position);
//将访问序列按顺序分成两份
vector<int>lower;//比起始磁头小的序列
vector<int>uper;//比起始磁头大的序列
for (int request : request_order)
{
if (request < start_position)
lower.push_back(request);
else
uper.push_back(request);
}
//对两个序列进行排序
sort(lower.rbegin(), lower.rend());
sort(uper.begin(), uper.end());
if (move_direction == DOWN_TO_UP)
{
//先下后上
for (int request : lower)
{
total_instance += abs(request - visit_order.back());
visit_order.push_back(request);
current_position = request;
}
for (int request : uper)
{
total_instance += abs(request - visit_order.back());
visit_order.push_back(request);
current_position = request;
}
}
else
{
//先上后下
for (int request : uper)
{
total_instance += abs(request - visit_order.back());
visit_order.push_back(request);
current_position = request;
}
for (int request : lower)
{
total_instance += abs(request - visit_order.back());
visit_order.push_back(request);
current_position = request;
}
}
}
InputAction:
/*
* @author W-nut
*/
#pragma once
#include <iostream>
#include <fstream>
#include <string>
#include "Constants.h"
using namespace std;
//初始从文件输入当前磁头的位置、磁头移动方向、磁道访问请求序列
void InputInit()
{
ifstream input;
input.open("input.txt",ios::in);
if (!input)
{
cout << "文件打开失败" << endl;
}
while (!input.eof())
{
input >> start_position;
input >> move_direction;
int visit;
while(input >> visit)
request_order.push_back(visit);
}
current_position = start_position;
input.close();
}
//输入选项
int InputSelection()
{
string selection;
cin >> selection;
return stoi(selection);
}
OutputAction:
/*
* @author W-nut
*/
#pragma once
#include <iostream>
using namespace std;
//输出菜单
void OutputMenu()
{
cout << "\t这是磁盘调度模拟程序!" << endl;
cout << "\t1.先来先服务(FCFS)\t\n"
<< "\t2.最短寻道时间(SSTF)\t\n"
<< "\t3.电梯扫描(SCAN)\t\n"
<< "\t4.显示准备信息(磁头依次访问的磁道号顺序)\t\n"
<< "\t5.退出\t\n";
cout << "\t请选择调度算法:";
}
//输出磁头访问顺序及路径长度
void OutputVisitOrder()
{
cout << "访问顺序为:";
for (int i : visit_order)
{
cout << i << "->";
}
cout << "end" << endl;
cout << "磁头总路径长度为:" << total_instance << endl;
}
//输出准备信息
void OutputInit()
{
cout << "起始磁头位置:" << start_position << endl;
cout << "当前磁头位置:" << current_position << endl;
cout << "磁头移动方向:" << move_direction << endl;
cout << "当前磁头访问请求序列为:";
for (int i : request_order)
cout << i << " ";
}
Constants:
/*
* @author W-nut
*/
#pragma once
#include <vector>
using namespace std;
//some selections
const int FCFS = 1;
const int SSTF = 2;
const int SCAN = 3;
const int SHOW = 4;
const int EXIT = 5;
//read or write direction flags
const int DOWN_TO_UP = 6; //从低到高
const int UP_TO_DOWN = 7; //从高到低
//the order of disk area
int start_position = 53; //起始磁头位置
int current_position = 53 ;//当前磁头位置
int move_direction = 6; //磁头初始移动方向从低到高
vector<int>request_order; //磁头访问请求序列
//the total instance
int total_instance = 0; //磁头走过的总磁道数
//the visit order
vector<int>visit_order; //访问顺序
//the instance between positions
vector<int>instance; //待访问序列与当前磁头位置之间的距离
//请求号结构体
struct Request_Num
{
int request_num; //当前请求号
int distance; //当前请求号与当前磁头的距离
};
//请求序列
vector<Request_Num>Request_Order;
五、Last but not least
传说五大秘术:点赞、评论、分享、收藏、打赏!
mua~~