磁盘调度算法

一、实验目的

1、了解磁盘结构以及磁盘上数据的组织方式;

2、掌握磁盘访问时间的计算方式;

3、掌握常用磁盘调度算法及其相关特性。

二、基本原理

FIFO:按访问请求到达的先后次序进行调度。

SSTF:优先选择使磁头臂从当前位置开始移动最少的磁盘I/O请求进行调度。

SCAN:要求磁头臂先沿一个方向移动,并在途中满足所有未完成的请求,直到它到达这个方向上的最后一个磁道,或者在这个方向上没有别的请求为止,后一种改进有时候称作LOOK策略。然后倒转服务方向,沿相反方向扫描,同样按顺序完成所有请求。

C-SCAN:在磁盘调度时,把扫描限定在一个方向,当沿某个方向访问到最后一个磁道时,磁头臂返回到磁盘的另一端,并再次开始扫描。

三、模块介绍

1、main()函数模块:初始化磁道序号和初始磁针位置并提供选择列表;

2、FIFO()函数模块:先进先出调度算法;

3、SSTF()函数模块:最短服务时间优先调度算法;

4、SCAN()函数模块:扫描(电梯)调度算法;

5、C-SCAN()函数模块:循环扫描调度算法。

四、流程图

五、代码实现

#include<iostream>
#include<cmath>
#include<algorithm>
#define MAXTRACK 1000
using namespace std;

int TRACK[MAXTRACK];										//初始磁道序列 
int track[MAXTRACK];										//排序后的磁道序列 
int start;													//初始磁针位置 
int tracknumber = 0;										//磁道总数 
int location;												//初始磁针当前(下一个)位置的下标 
double length;												//总寻道长度 

void FIFO(int TRACK[], int tracknumber, int start) {
	double length = 0;
	cout<<"Initial track position:" << start << endl;
	for(int i = 0; i < tracknumber; i++) {
		length += abs(TRACK[i] - start);					//按初始顺序将长度累加 
		cout << "The track number of the next access is:" << TRACK[i] << endl;
		cout << "The length of the seek is:" << abs(TRACK[i] - start) << endl;
		start = TRACK[i];									//移动磁针位置 
	}
	cout << "The average seek length is:" << length / tracknumber << endl;
}

void SSTF(int TRACK[], int tracknumber, int start) {
	int left, right;										//left:左移"指针";right:右移"指针" 
	bool flag;												//false:左移"指针"到达边界;true: 右移"指针"到达边界 
	length = 0;
	for(int i = 0; i < tracknumber; i++)
		track[i] = TRACK[i];
	sort(track, track + tracknumber);
	if(start >= track[tracknumber - 1]) {					//初始磁针位置比所有访问位置都大 
		for(int i = tracknumber - 1; i >= 0; i--) {
			length += start - track[i];
			cout << "The track number of the next access is:" << track[i] << endl;
			cout << "The length of the seek is:" << abs(track[i] - start) << endl;
			start = track[i];
		}
	}
	else if(start <= track[0]) {							//初始磁针位置比所有访问位置都小 
		for(int i = 0; i < tracknumber; i++) {
			length += track[i] - start;
			cout << "The track number of the next access is:" << track[i] << endl;
			cout << "The length of the seek is:" << abs(track[i] - start) << endl;
			start = track[i];
		}
	}
	else {													//初始磁针位置在访问区域中 
		for(int i = 1; i < tracknumber; i++)
			if(start > track[i - 1] && start <= track[i])
				location = i;								//定位磁针 
		left = location - 1;
		right = location;
		while(true) {
			if(abs(start - track[left]) >= abs(start - track[right])) {
				length += abs(start - track[right]);		//右侧更近 
				cout << "The track number of the next access is:" << track[right] << endl;
				cout << "The length of the seek is:" << abs(track[right] - start) << endl;
				start = track[right];
				if(right == tracknumber - 1) {				//到达右边界 
					flag = true;
					break;
				}
				right++;
			}
			else {											
				length += abs(start - track[left]);			//左侧更近 
				cout << "The track number of the next access is:" << track[left] << endl;
				cout << "The length of the seek is:" << abs(track[left] - start) << endl;
				start = track[left];
				if(left == 0) {								//到达左边界 
					flag = false;
					break;
				}
				left--;
			}
		}
		if(flag) {											//左移"指针"一直左移 
			while(true) {
				if(left == 0) {	
					length += abs(start - track[left]);
					cout << "The track number of the next access is:" << track[left] << endl;
					cout << "The length of the seek is:" << abs(track[left] - start) << endl;
					break;
				}
				else {
					length += abs(start - track[left]);
					cout << "The track number of the next access is:" << track[left] << endl;
					cout << "The length of the seek is:" << abs(track[left] - start) << endl;
					start = track[left--];
				}  
			} 
		}
		else {												//右移"指针"一直右移 
			while(true) {
				if(right == tracknumber-1) {	
					length += abs(start - track[right]);
					cout << "The track number of the next access is:" << track[right] << endl;
					cout << "The length of the seek is:" << abs(track[right] - start) << endl;
					break;
				}
				else {
					length += abs(start - track[right]);
					cout << "The track number of the next access is:" << track[right] << endl;
					cout << "The length of the seek is:" << abs(track[right] - start) << endl;
					start = track[right++];
				}  
			} 
		}
	}
	cout << "The average seek length is:" << length / tracknumber << endl;
}

void SCAN(int TRACK[], int tracknumber, int start) {
	bool flag;												//false:优先向左移动;true:优先向右移动 
	length = 0;
	for(int i = 0; i < tracknumber; i++)
		track[i] = TRACK[i];
	sort(track, track + tracknumber);
	for(int i = 1; i < tracknumber; i++) {
		if(start > track[i - 1] && start <= track[i]) {
			location = i;									//定位磁针 
			if(abs(track[i] - start) > abs(track[i - 1] - start)) flag = false;
			else flag = true;
			break;											//确定磁针距离最近的两端磁道中更近的磁道所在方向 
		}
	}
	if(!flag) {												//先左移 
		for(int i = location - 1; i >= 0; i--) {
			length += abs(start - track[i]);
			cout << "The track number of the next access is:" << track[i] << endl;
			cout << "The length of the seek is:" << abs(track[i] - start) << endl;
			start = track[i];
		}
		for(int i = location; i < tracknumber; i++) {		//调转方向 
			length += abs(start - track[i]);
			cout << "The track number of the next access is:" << track[i] << endl;
			cout << "The length of the seek is:" << abs(track[i] - start) << endl;
			start = track[i];
		}
	}
	else {													//先右移 
		for(int i = location; i < tracknumber; i++) {
			length += abs(start - track[i]);
			cout << "The track number of the next access is:" << track[i] << endl;
			cout << "The length of the seek is:" << abs(track[i] - start) << endl;
			start = track[i];
		}
		for(int i = location - 1; i >= 0; i--) {			//调转方向
			length += abs(start-track[i]);
			cout << "The track number of the next access is:" << track[i] << endl;
			cout << "The length of the seek is:" << abs(track[i] - start) << endl;
			start = track[i];
		}
	}
	cout << "The average seek length is:" << length / tracknumber << endl;
}

void C_SCAN(int TRACK[], int tracknumber, int start) {
	bool flag;												//false:优先向左移动;true:优先向右移动 
	length = 0;
	for(int i = 0; i < tracknumber; i++)
		track[i] = TRACK[i];
	sort(track, track + tracknumber);
	for(int i = 1; i < tracknumber; i++) {
		if(start > track[i - 1] && start <= track[i]) {
			location = i;									//定位磁针
			if(abs(track[i] - start) > abs(track[i - 1] - start)) flag = false;
			else flag = true;
			break;											//确定磁针距离最近的两端磁道中更近的磁道所在方向
		}
	}
	if(!flag) {												//先左移
		for(int i = location - 1; i >= 0; i--) {
			length += abs(start - track[i]);
			cout << "The track number of the next access is:" << track[i] << endl;
			cout << "The length of the seek is:" << abs(track[i] - start) << endl;
			start = track[i];
		}
		for(int i = tracknumber - 1 ; i >= location ; i--) {//从另一端继续 
			length += abs(start - track[i]);
			cout << "The track number of the next access is:" << track[i] << endl;
			cout << "The length of the seek is:" << abs(track[i] - start) << endl;
			start = track[i];
		}
	}
	else {													//先右移
		for(int i = location; i < tracknumber; i++) {
			length += abs(start - track[i]);
			cout << "The track number of the next access is:" << track[i] << endl;
			cout << "The length of the seek is:" << abs(track[i] - start) << endl;
			start = track[i];
		}
		for(int i = 0; i <= location - 1; i++) {			//从另一端继续
			length += abs(start-track[i]);
			cout << "The track number of the next access is:" << track[i] << endl;
			cout << "The length of the seek is:" << abs(track[i] - start) << endl;
			start = track[i];
		}
	}
	cout << "The average seek length is:" << length / tracknumber << endl;
}

int main(void) {
	int choice;
	cout << "****************磁盘调度算法****************" << endl;
	cout << "Please enter the track number to access (1-1000, enter -1 to stop input):" << endl;
	while (true) {											//输入访问的磁道序号 
		cin >> TRACK[tracknumber];
		if (TRACK[tracknumber] == -1)
			break;
		else if(TRACK[tracknumber] > MAXTRACK || TRACK[tracknumber] < 0) {
			cout << "Input error, please re-enter:" << endl;
			continue;
		}
		tracknumber++;
	}
	for(int i = 0; i < tracknumber; i++)
		track[i] = TRACK[i];
	sort(track, track + tracknumber);
	cout<<"Please enter the initial position of the magnetic needle : ";
	cin >> start;											//输入初始磁针位置 
	while(true) {
		if(start < 0 || start > MAXTRACK) {
			cout << "Input error, please re-enter:";
			cin >> start;
		}
		else
			break;
	}
	cout << "There are currently " << tracknumber << " tracks to access." << endl;
	cout << "The sequence of the input track is:";
	for(int i = 0; i < tracknumber; i++) {
		if(i != tracknumber - 1)
			cout << TRACK[i] << "->";
		else
			cout << TRACK[i] << endl;
	}
	cout << "The sorted track sequence is:";
	for(int i = 0; i < tracknumber; i++) {
		if(i != tracknumber - 1)
			cout << track[i] << "->";
		else
			cout << track[i] << endl;
	}
	cout << "The initial position of the magnetic needle:" << start << endl;
	while(true) {
		cout << "1.FIFO" << endl;
		cout << "2.SSTF" << endl;
		cout << "3.SCAN" << endl;
		cout << "4.C-SCAN" << endl;
		cout << "Please select disk scheduling algorithm (Enter 0 to exit the program):";
		cin >> choice;
		if(choice >= 0 && choice <= 4) {
			switch(choice) {
				case 0:
					exit(0);
				case 1:
					FIFO(TRACK, tracknumber, start);
					break;
				case 2:
					SSTF(TRACK, tracknumber, start);
					break;
				case 3:
					SCAN(TRACK, tracknumber, start);
					break;
				case 4:
					C_SCAN(TRACK, tracknumber, start);
					break;
			}
		}
		else
			cout << "Input error, please re-enter!" << endl;
	}
}

六、实验结果与分析 

1、FIFO

        磁针从100开始,按照初始磁道序列进行扫描得出结果。

2、SSTF

       先判断初始磁针位置与访问区间的相对位置,可知初始磁针位置在访问区间中,定位距离磁针最近的左右两个磁道的位置(90和150)并用指针标记,依次计算比较最近的两端磁道与磁针当前的距离,每次向更近的磁道方向扫描并移动该方向上的指针。本题数据左指针先到达边界(18),调转方向继续扫描,直到访问到右边界(184)时停止扫描,计算出结果。

 3、SCAN

        磁针从100开始先定位距离最近的两个磁道(90和150),确定更近的磁道方向(左侧)开始扫描,当扫描到左边界(18)时,调转方向继续扫描,直到扫描到右边界(184)时停止扫描,计算出结果。

4、C-SCAN

        磁针从100开始先定位距离最近的两个磁道(90和150),确定更近的磁道方向(左侧)开始扫描,当扫描到左边界(18)时,从对侧(184)继续扫描,直到扫描到之前定位的右侧磁道(150)时停止扫描,计算出结果。

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
磁盘调度算法操作系统中的重要组成部分,它负责决定磁盘上的数据访问顺序,以提高磁盘的访问效率。常见的磁盘调度算法包括先来先服务(FCFS)、最短寻道时间优先(SSTF)、扫描算法(SCAN)等。在JavaFX中,我们可以通过图形化界面来实现磁盘调度算法的可视化演示。 首先,我们可以利用JavaFX提供的Canvas类来创建一个模拟磁盘的可视化界面,用于展示磁盘上的数据分布以及磁头的移动情况。然后,通过JavaFX的事件响应机制,可以实现用户输入磁盘访问请求的功能,比如输入某个磁道的请求,然后演示磁头移动的过程。 接着,我们可以编写相应的Java代码来实现各种磁盘调度算法的逻辑。比如实现FCFS算法时,可以按照请求的先后顺序来访问磁道;而实现SSTF算法时,则需要动态地选择距离磁头最近的磁道进行访问;而SCAN算法则需要模拟磁头来回扫描磁道的移动过程。 最后,将磁盘模拟界面和各种调度算法的逻辑结合起来,通过JavaFX的界面刷新机制,实时展示磁头的移动轨迹和磁盘的访问顺序。这样用户就可以直观地了解不同调度算法对磁盘访问效率的影响,从而更好地理解操作系统中的磁盘调度原理。这样的可视化演示不仅可以帮助学生更好地学习磁盘调度算法,也为开发人员提供了一个直观的工具来优化磁盘访问性能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

有为肥宅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值