操作系统实验——模拟实现磁盘调度管理

一、实验要求

1.基础知识
掌握磁盘调度的相关内容,对磁盘结构及调度算法有深入的理解。
2.具体要求
(1)选择2~3中磁盘调度算法(先来先服务、最短寻道时间优先、电梯算法)
(2)输入:当前磁头位置、磁头移动方向、磁道访问请求序列
(3)输出:磁头依次访问的磁道号顺序,计算磁头移动的总磁道数

二、运行截图

图一  初始数据
在这里插入图片描述

图二  FCFS调度
在这里插入图片描述
图三  SSTF
在这里插入图片描述

图四  SCAN

三、代码结构

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~~

  • 5
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值