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

本文介绍了如何设计和实现磁盘调度算法,包括FCFS、SSTF和SCAN,通过模拟磁盘访问顺序,计算平均寻道长度,以优化磁盘I/O性能。
摘要由CSDN通过智能技术生成

一、实验目的

   磁盘是高速、大容量、旋转型、可直接存取的存储设备。它作为计算机系统的辅助存储器,担负着繁重的输入输出工作,在现代计算机系统中往往同时会有若干个要求访问磁盘的输入输出要 求。系统可采用一种策略,尽可能按最佳次序执行访问磁盘的请求。由于磁盘访问时间主要受寻道 时间 T 的影响,为此需要采用合适的寻道算法,以降低寻道时间。本实验要求学生模拟设计磁盘调 度程序,观察调度程序的动态运行过程。通过实验让学生理解和掌握磁盘调度的职能。

二、实验要求

   模拟电梯调度算法(SCAN)及最短寻道时间优先算法(SSTF),对磁盘进行移臂操作,列出 基于该种算法的磁道访问序列,计算平均寻道长度。

三、实验原理

3.1假设磁盘只有一个盘面,并且磁盘是可移动头磁盘。

3.2磁盘是可供多个进程共享的存储设备,但一个磁盘每个时刻只能为一个进程服务。当有进程在 访问某个磁盘时,其它想访问该磁盘的进程必须等待,直到磁盘一次工作结束。当有多个进程 提出输入输出请求而处于等待状态时,可选用适当的磁盘调度算法从若干个等待访问者中选择 一个进程,让它访问磁盘。为此设置“驱动调度”进程。

3.3“初始化”进程建立一张“进程请求 I/O”表,列出等待访问磁盘的进程要求访问的磁道,表的格式如下:

3.4“磁盘调度”的功能是扫描“请求 I/O”表并根据用户所选算法重新排序,列出基于该种算法 的磁道访问序列,计算平均寻道长度

四、结果展示

   本次实验完成了FCFS、SSTF、SCAN磁盘调度算法。

4.1 FCFS

初始化信息:

初始化磁头的初始磁道号,输入申请访问磁盘的柱面号个数和相应的柱面号。

接下来算法将根据提出申请的时间依次响应每个请求,并算出磁头从上一个柱面号到当前柱面号所经过的磁道数。

   最后,计算平均寻道长度。

4.2 SSTF

   同FCFS,先初始化信息。

   然后SSTF算法按照响应离当前磁头位置最近的磁道的原则,依次响应所有请求。

   最后,计算平均寻道长度。

4.3 SCAN

   同FCFS、SSTF,先初始化信息:

   磁头朝着一个方向运动,沿途响应请求,当磁头运动到磁盘的边界或者中心时,掉头。

   所以,SCAN算法的响应顺序为:

   由于初始磁头运动的方向为指向磁盘中心,所以,响应访问序列呈现先增大后减小的特征。最后,计算平均寻道时间。

   下面展示初始磁头运动方向指向磁盘边界:

   相应的,呈现的是先减小后增大的特征。

五、实验代码

#include<iostream>
#include<iomanip>
#include<string.h>
#include<Windows.h>
#include<time.h>
using namespace std;

struct disk_FCFS {
	int move;//磁头从上一个柱面运动到该柱面经过的轨道数
	int number;//柱面号

	disk_FCFS() {
		this->move = 0;
		this->number = 0;
	}
};

//FCFS
void solve1() {
	int process_num, sum = 0;
	float res;
	struct disk_FCFS disk1[100];
	cout << "请输入初始轨道号" << endl;
	cin >> disk1[0].number;
	cout << "请输入需要访问磁盘的进程数目" << endl;
	cin >> process_num;

	//输入每个进程需要访问磁盘的轨道号
	cout << "请输入待访问柱面:" << endl;
	for (int i = 1; i <= process_num; i++) {
		cin >> disk1[i].number;
	}
	for (int i = 1; i <= process_num; i++) {
		disk1[i].move = abs(disk1[i - 1].number - disk1[i].number);
		sum += disk1[i].move;
	}
	res = float(sum) / process_num;
	cout << "(从" << disk1[0].number << "号轨道开始)" << endl;
	cout << "被访问的下一个轨道号  移动距离(轨道数)" << endl;
	for (int i = 1; i < process_num + 1; i++) {
		cout << setiosflags(ios::left);
		cout << setw(22) << disk1[i].number;
		cout << disk1[i].move << endl;
		Sleep(1000);
	}
	cout << "磁头走过总道数为:" << sum << endl;
	cout << "平均寻道长度: " << setprecision(1) << fixed << res << endl;
	return;
}

struct disk_SSTF {
	int finish = 0;
	int move;
	int number;

	disk_SSTF() {
		this->finish = 0;
		this->move = 0;
		this->number = 0;
	}
};

//SSTF
void solve2() {
	int process_num, index = 0, index1 = 0, temp, minint = 999, sum = 0;
	float res;
	struct disk_SSTF disk1[200];
	cout << "请输入初始轨道号" << endl;
	cin >> disk1[0].number;
	cout << "请输入需要访问磁盘的进程数目" << endl;
	cin >> process_num;
	cout << "请输入待访问柱面:" << endl;
	for (int i = 1; i <= process_num; i++) {
		cin >> disk1[i].number;
	}
	cout << "(从" << disk1[0].number << "号轨道开始)" << endl;
	cout << "被访问的下一个轨道号  移动距离(轨道数)" << endl;
	for (int i = 1; i <= process_num; i++) {
		for (int j = 1; j <= process_num; j++) {
			if (disk1[j].finish == 0) {
				temp = abs(disk1[j].number - disk1[index1].number);
				if (temp < minint) {
					index = j;
					minint = temp;
				}
			}
		}
		disk1[index].finish = 1;
		disk1[index].move = minint;
		sum += disk1[index].move;
		index1 = index;
		minint = 999;
		cout << setiosflags(ios::left);
		cout << setw(22) << disk1[index].number;
		cout << disk1[index].move << endl;
		Sleep(1000);
	}
	res = float(sum) / process_num;
	cout << "磁头走过总道数为:" << sum << endl;
	cout << "平均寻道长度: " << setprecision(1) << fixed << res << endl;
	return;
}

//如果磁头向内运动,那么如果所有访问柱面号中当前访问的柱面号是最大的,说明已经运动到顶端(磁盘中心),磁头转向
//否则,说明还没有运动到顶端(磁盘中心),磁头不转向
int Max(int* cyclist, int n, int num) {
	for (int i = 0; i < n; i++) {
		if (cyclist[i] > num) {
			return 0;
		}
	}
	return 1;
}

//如果磁头向外运动,那么如果所有访问柱面号中当前访问的柱面号是最小的,说明已经运动到底端(磁盘外围),磁头转向
//否则,说明还没有运动到底端(磁盘外围),磁头不转向
int Min(int* cyclist, int n, int num) {
	for (int i = 0; i < n; i++) {
		if (cyclist[i] < num) {
			return 0;
		}
	}
	return 1;
}

//0表示磁头向外运动,柱面号逐渐减小,1表示磁头向内运动,柱面号逐渐增大 
int SCAN(int* cyc_list, int* cyc_order, int n, int start, int dir) {
	int sum, max_int, min_value, index, tag[100] = { 0 };
	sum = 0;
	for (int i = 0; i < n; i++) {
		max_int = 9999;
		for (int j = 0; j < n; j++) {
			if (dir == 1 && cyc_list[j] > start && tag[j] == 0) {//cyc_list表示待执行柱面
				min_value = cyc_list[j] - start;
				if (min_value < max_int) {
					max_int = min_value;
					index = j;//记录距离最小的待执行柱面号的索引
				}
			}
			else if (dir == 0 && cyc_list[j] < start && tag[j] == 0) {
				min_value = abs(cyc_list[j] - start);
				if (min_value < max_int) {
					max_int = min_value;
					index = j;//记录距离最小的待执行柱面号的索引
				}
			}
		}
		//判断是否需要转向
		int x = 0,x_max=0,x_min=0x3f3f3f3f;
		for (int i = 0; i < n; i++) {
			if (cyc_list[i] > x_max) {
				x_max = cyc_list[i];
			}
			if (cyc_list[i] < x_min) {
				x_min = cyc_list[i];
			}
		}
		if (dir == 1 && Max(cyc_list, n, cyc_list[index])) {
			dir = 0;
			sum += 2*(500 - x_max);
		}
		else if (Min(cyc_list, n, cyc_list[index])) {
			dir = 1;
			sum += 2*x_min;
		}
		sum += max_int;//累积磁头移动轨道数
		tag[index] = 1;
		cyc_order[i] = cyc_list[index];
		start = cyc_list[index];
	}
	return sum;
}

//SCAN
void solve3() {
	int cyc_list[100], cyc_order[100], n, start, dir,ans=0;
	cout << "请输入磁臂初始移动方向(1向内,0向外):";
	cin >> dir;
	cout << "请输入初始柱面和待执行柱面数量:";
	cin >> start >> n;
	cout << "请输入待执行柱面:";
	for (int i = 0; i < n; i++)
		cin >> cyc_list[i];
	ans = SCAN(cyc_list, cyc_order, n, start, dir);
	cout << "SCAN走道顺序为:";
	for (int i = 0; i < n; i++) {
		cout << cyc_order[i];
		if (i + 1 != n) {
			cout << " -> ";
		}
		Sleep(1000);
	}
	cout << endl;
	cout << "磁头走过总道数为:" << ans << endl;
	float res = float(ans) / n;
	cout << "平均寻道长度: " << setprecision(1) << fixed << res << endl;
	return;
}

int main() {
	int op;
	while (1) {
		cout << "请选择算法,输入1表示FCFS算法,输入2表示SSTF算法,输入3表示SCAN算法,输入0表示退出" << endl;
		cin >> op;
		system("cls");
		if (op == 0 || op == 1 || op == 2 || op == 3) {
			if (op == 0) {
				return 0;
			}
			else if (op == 1) {
				cout << "FCFS" << endl;
				solve1();
			}
			else if (op == 2) {
				cout << "SSTF" << endl;
				solve2();
			}
			else if (op == 3) {
				cout << "SCAN" << endl;
				solve3();
			}
		}
		else {
			cout << "输入错误,请根据提示正确输入" << endl;
			continue;
		}
	}
}

 

  • 20
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值