磁盘调度管理_C++_SSTF_SCAN

1.最短寻道优先算法SSTF:该算法选择这样的进程:其要求访问的磁道与当前磁头所在的磁道距离最近,以使每次的寻道时间最短。

 

2.扫描算法SCAN:该算法不仅考虑到欲访问的磁道与当前磁道间的距离,更优先考虑的是磁头当前的移动方向。例如,当磁头正在自里向外移动时,SCAN算法所考虑的下一个访问对象,应是其欲访问的磁道既在当前磁道之外,又是距离最近的。这样自里向外地访问,直至再无更外的磁道需要访问时,才将磁臂换向为自外向里移动。

 

 

#include<iostream>
#include<time.h>
#include<Windows.h>
#include<string>
using namespace std;
#define MAX 200

int Move;//移动距离
int  direction;//移动方向
int set[MAX];//存储访问序列
int lable[MAX];//标签数组,存放整理后的序列
int lenth = 0;//个数,即有效占用数组里的的长度
int x = 0;//记磁头处标号

//创建访问序列
void Create() {
	int n = 0;
	int k = 0;
	//用前初始化
	for (int i = 0;i < MAX;i++) {
		set[i] = -1;
		lable[i] = -1;
	}
	retry:
	cout << "========================================" << endl;
	cout << "#输入1自动生成#\n#输入2手动输入#" << endl;
	cout << "========================================" << endl;
	cout << "请输入:";
	cin >> k;
	if (k == 1) {
		cout << "========================================" << endl;
		cout << "请输入磁道个数以生成随机磁道号:";
		cin >> n;
		cout << "生成磁道号为 :";
		srand((unsigned)time(NULL));  //给srand提供种子,unsigned int类型,取值范围0-65565
		for (int i = 0;i < n;i++)
		{
			set[i] = (rand() % MAX) + 1;  //rand根据srand种子值返回一个随机数
			cout << set[i] << " ";

		}
	}
	else if(k == 2) {
		cout << "========================================" << endl;
		cout << "请输入磁道个数:";		
		cin >> n;
		cout << "输入磁道号为 :";
		for (int i = 0;i <n;i++) {
			cin >> set[i];
		}
	}
	else {
		system("cls");
		goto retry;
	}

	cout << "\n========================================\n" << endl;
	lenth = n;
}

//移动距离计算
int Cal(int a, int b) {
	return(a > b ? a - b : b - a);
}

//路径显示
void Showpath(int a[], int x, int len) {
	cout << "========================================" << endl;
	cout << "从" << x << "号磁道开始:" << endl;

	for (int i = 1;i < len + 5;i++) {
		int j = i;
		if (a[1] == x) {
			j = i + 1;
		}

		//将选定已有随机磁道开始时set[len]为-1情况剔除
		if (a[j] >= 0 && a[j] <= MAX) {
			cout << "到下一个磁道是:" << a[j] << "\t移动距离为:" << Cal(a[j - 1], a[j]) << endl;
			Sleep(500);
		}
	}
	cout << "========================================" << endl;//38*=
}

//平均寻道长度
void Cal_aver(int a[], int x, int len) {
	float all = 0;
	float average = 0;
	for (int i = 1;i < len + 1;i++) {
		all += Cal(a[i - 1], a[i]);
	}
	average = all / len;
	cout << "平均寻道长度为:" << average << endl;
	cout << "========================================" << endl;
}

//SSTF最短寻道
void SSTF(int a[], int x, int len) {
	cout << "========================================" << endl;
	cout << "已选择从" << x << "号" << "开始执行:" << endl;
	lable[0] = x;

	int m = 0;
	int temp = 0;

	//找出访问序列
	for (int i = 0;i < len;i++) {
		int m = i;

		//找到离当前最近的一磁道
		for (int j = i;j < len;j++) {
			//set[j+1]条件防止数据读取超出len长度
			if (Cal(set[j + 1], lable[i]) < Cal(set[m], lable[i]) && set[j + 1] >= 0) {
				m = j + 1;
				temp = set[j + 1];
			}
			else {
				temp = set[m];
			}

		}
		lable[i + 1] = temp;
		//找到后,将其跳出下一循环(跳出循环时总会是m
		int temp1 = set[m];
		set[m] = set[i];
		set[i] = temp1;

	}
	Showpath(lable, x, len);
	Cal_aver(lable, x, len);
}

//SCAN电梯调度
void SCAN(int a[], int x, int len) {
	cout << "========================================" << endl;
	cout << "已选择从" << x << "号" << "开始执行:" << endl;

	int m = 0;
	int temp = 0;

	int* p1 = new int[len];	//存放排列好的序列
	for (int i = 0; i < len; i++)p1[i] = set[i];

	//排列好的磁道号自小至大冒泡
	for (int i = 0;i < len - 1;i++) {
		for (int j = 0;j < len - 1 - i;j++) {
			if (p1[j + 1] < p1[j]) {
				temp = p1[j + 1];
				p1[j + 1] = p1[j];
				p1[j] = temp;
			}
		}
	}

	//选出最近一磁道号,确定扫描方向
	lable[0] = x;
	m = 0;
	int temp_2 = 0;//x若在p1[[]中,存p1[]中x所在下标,否则存与x最近值的下标
	for (int j = 0;j < len - 1;j++) {

		//条件p1[j+1]跳过与lable下标0,1相同的磁盘号
		if (Cal(p1[j + 1], lable[0]) < Cal(p1[m], lable[0]) && p1[j + 1] != x) {
			m = j + 1;
			temp = p1[j + 1];
		}
		else {
			temp = p1[m];
		}
		lable[1] = temp;
		if (p1[j] == x) {
			temp_2 = j;
			break;
		}
		else {
			temp_2 = m;
		}
	}

	//若电梯上楼
	if (lable[1] - lable[0] > 0) {
		direction = 1;
	}
	else {
		direction = 0;
	}

	//给lable[]整上
	m = temp_2;//此m为p1[]中被指定开始那个磁盘号的下标
	temp = m;
	int k = p1[m];
	for (int i = 1;i < len + 1;i++) {
		//若下楼
		if (direction == 0) {
			if (m > 0) {
				//保证lable[]不出错
				if (lable[0] != p1[m] && i == 1) {
					i += 1;
					lable[i] = p1[m - 1];
					m--;
				}
				else {
					lable[i] = p1[m - 1];
					m--;
				}
			}
			if (m <=0) {
				direction = 1;
				m = temp;
				//保证lable[]不出错
				if (lable[0] == k) {
					i += 1;
				}
			}
		}
		else {
			//if防止访问出界
			if (m < len - 1) {
				if (lable[0] != p1[m] && i == 1) {
					i += 1;
					lable[i] = p1[m + 1];
					m++;
				}
				else {
					lable[i] = p1[m + 1];
					m++;
				}
			}
			if (m >= len-1) {
				direction = 0;
				m = temp;
				if (lable[0] == k) {
					i += 1;
				}
			}
		}
	}

	Showpath(lable, x, len);
	Cal_aver(lable, x, len);
	delete[] p1;
}

int main() {
	int select = 0;

	system("mode con:cols=40 lines=40");
	system("color  10");
	Sleep(100);
	system("color  20");
	Sleep(100);
	system("color  30");
	Sleep(100);
	system("color  40");
	Sleep(100);
	system("color  50");
	Sleep(100);
	system("color  60");
	Sleep(100);
	system("color  e0");

	while (1) {
		cout << "========================================" << endl;
		cout << "================= ORDER=================" << endl;
		cout << "===============0:退出程序==============" << endl;
		cout << "===============1:SSTF算法==============" << endl;
		cout << "===============2:SCAN算法==============" << endl;
		cout << "========================================" << endl;
		cout << "\n你的选择:";
		cin >> select;
		cout << "正在执行:" << endl;
		switch (select)
		{
		case 0: {
			cout << "\n退出成功!" << endl;
			system("color  10");
			Sleep(100);
			system("color  20");
			Sleep(100);
			system("color  30");
			Sleep(100);
			system("color  40");
			Sleep(100);
			system("color  50");
			Sleep(100);
			system("color  60");
			Sleep(100);
			system("color  0f");
			exit(0);

		}
		case 1: {
			Create();
			Sleep(500);
			cout << "========================================" << endl;
			cout << "请选择磁头处当前磁道号(1~" << MAX << "):";
			cin >> x;
			SSTF(set, x, lenth);
			system("pause");
			system("cls");
			break;
		}
		case 2: {
			Create();
			Sleep(500);
			cout << "========================================" << endl;
			cout << "请选择磁头处当前磁道号(1~" << MAX << "):";
			cin >> x;
			SCAN(set, x, lenth);
			system("pause");
			system("cls");
			break;
		}
		default: {
			system("cls");
		}
		}
	}
	return 0;
}

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值