磁盘调度算法

目录
第1章 设计背景 3
第2章 需求分析 3
2.1环境分析 3
2.1.1语言 3
2.1.2运行软件 3
2.2 技术分析 3
2.3 业务需求分析 4
2.4功能模块分析。 5
2.4.1 FCFS算法分析 5
2.4.2 SSTF算法分析 6
2.4.3 SCAN算法分析 6
2.4.4 CSCAN算法分析 7
第3章 总体设计 8
3.1总体设计流程图 8
3.2 功能模块分析 9
3.2.1 二分法排序实现 9
3.2.2 FCFS算法实现 9
3.2.3 SSTF算法实现 10
3.2.3 SCAN算法实现 10
3.2.4 C-SCAN算法实现 11
3.2.5 操作界面实现 11
第4章 功能调试 11
4.1 实验源码 11
4.2 实验调试结果 17
4.2.1 FIFO 17
4.2.2 SSTF 18
4.2.3 SCAN 18
4.2.4 C-SCAN 19
4.2.5 退出 19
第5章 总结 19

第1章 设计背景
磁盘调度算法是操作系统中的重要内容之一,它的主要作用是优化磁盘的读写效率,提高系统的性能。本次实验旨在通过设计不同的磁盘调度算法,比较它们在不同情况下的性能表现,了解磁盘结构以及磁盘上数据的组织方式,掌握磁盘访问时间的计算方式,掌握常用磁盘调度算法及其相关特性。
第2章 需求分析
2.1环境分析
2.1.1语言
本实验使用C语言进行程序设计。C语言是一门面向过程的、抽象化的通用程序设计语言,广泛应用于底层开发。C语言能以简易的方式编译、处理低级存储器。C语言是仅产生少量的机器语言以及不需要任何运行环境支持便能运行的高效率程序设计语言。它既具有高级语言的特点,又具有汇编语言的特点。C语言特点:简洁的语言、具有结构化的控制语句、丰富的数据类型、丰富的运算符、可对物理地址进行直接操作、代码具有较好的可移植性、可生成高质量、目标代码执行效率高的程序
2.1.2运行软件
Microsoft Visual Studio(简称VS)是美国微软公司的开发工具包系列产品。VS是一个基本完整的开发工具集,它包括了整个软件生命周期中所需要的大部分工具,如UML工具、代码管控工具、集成开发环境(IDE)等等。所写的目标代码适用于微软支持的所有平台,包括[Microsoft Windows](https://baike.baidu.com/item/Microsoft Windows)、Windows Mobile、[Windows CE](https://baike.baidu.com/item/Windows CE)、[.NETFramework](https://baike.baidu.com/item/.NET Framework)、.NET Compact Framework和Microsoft Silverlight 及Windows Phone Visual Studio是最流行的Windows平台应用程序的集成开发环境,目前最新版本为 Visual Studio 2019 版本。Visual studio 2019具有良好的性能和更快运行速度和简洁的启动窗口,更好的搜索功能,代码整理功能
2.2 技术分析
寻找时间 Ts: 活动头磁盘在读写信息前,将磁头移动到指定磁道所需要的时间。这个时间除跨越n条磁道的时间外,还包括启动磁臂的时间s,即:Ts=mn+s。式中,m是与磁盘驱动器速度有关的常数,约为0.2ms,磁臂的启动时间约为2ms。
延迟时间Tr: 磁头定位到某一磁道的扇区(块号)所需要的时间,设磁盘的旋转速度为r,则:Tr=1/(2
r) 。对于硬盘,典型的旋转速度为5400r/m,相当于一周11.1ms,则Tr为5.55ms;对于软盘,其旋转速度在300~600r/m之间,则Tr 为 50~100ms。
传输时间Tt :从磁盘读出或向磁盘写入数据所经历的时间,这个时间取决于每次所读/写的字节数b和磁盘的旋转速度:Tt=b/(r∗N)。式中,r为磁盘每秒钟的转数;N为一个磁道上的字节数。
在磁盘存取时间的计算中,寻道时间与磁盘调度算法相关,下面将会介绍分析几种算法,而延迟时间和传输时间都与磁盘旋转速度相关,且为线性相关,所以在硬件上,转速是磁盘性能的一个非常重要的参数。
总平均存取时间Ta
可以表示为: Ta = Ts + Tr + Tt
注意:在实际的磁盘I/O操作中,存取时间与磁盘调度算法密切相关。调度算法直接决定寻道时间,从而决定总的存取时间。
 先来先服务(First Come First Served,FCFS)。FCFS算法根据进程请求访问磁盘的先后顺序进行调度,这是一种最简单的调度算法。该算法的优点是具有公平性。如果只有少量进程需要访问,且大部分请求都是访问簇聚的文件扇区,则有望达到较好的性能;但如果有大量进程竞争使用磁盘,那么这种算法在性能上往往接近于随机调度。所以,实际磁盘调度中考虑一些更为复杂的调度算法。算法思想:按访问请求到达的先后次序服务。
 最短寻道时间优先算法SSTF:SSTF算法选择调度处理的磁道是与当前磁头所在磁道距离最近的磁道,以使每次的寻找时间最短。当然,总是选择最小寻找时间并不能保证平均寻找时间最小,但是能提供比FCFS算法更好的性能。这种算法会产生“饥饿”现象。算法思想:优先选择距当前磁头最近的访问请求进行服务,主要考虑寻道优先。
 SCAN(电梯算法):SCAN算法在磁头当前移动方向上选择与当前磁头所在磁道距离最近的请求作为下一次服务的对象。由于磁头移动规律与电梯运行相似,故又称为电梯调度算法。SCAN算法对最近扫描过的区域不公平,因此,它在访问局部性方面不如FCFS算法和SSTF算法好。算法思想:当设备无访问请求时,磁头不动;当有访问请求时,磁头按一个方向移动,在移动过程中对遇到的访问请求进行服务,然后判断该方向上是否还有访问请求,如果有则继续扫描;否则改变移动方向,并为经过的访问请求服务,如此反复
 C-SCAN(循环扫描)算法:CSCAN调度算法是在扫描算法的基础上改进的,为了减少延迟,规定磁头单向移动,例如,只是自里向外移动,从当前位置开始沿磁头的移动方向去选择离当前磁头最近的那个柱面访问,如果沿磁头的方向无请求时,磁头立即返回到最里面的欲访问的柱面,再亦即将最小柱面号紧接着最大柱面号构成循环。在磁盘调度时,把扫描限定在一个方向,当沿某个方向访问到最后一个磁道时,磁头臂返回到磁盘的另一端,并再次开始扫描。
2.3 业务需求分析
加深对磁盘调度算法的理解,进一步掌握先来先服务FCFS、最短寻道时间优先算法SSTF、SCAN和循环SCAN算法的实现方法。磁盘调度的目的是要尽可能降低磁盘的寻道时间,以提高磁盘 I/O 系统的性能。
2.4功能模块分析。
2.4.1 FCFS算法分析
假设磁盘访问序列:98,183,37,122,14,124,65,67。读写头起始位置:53。求:磁头服务序列和磁头移动总距离(道数)。由题意和先来先服务算法的思想,得到下图所示的磁头移动轨迹。由此:磁头服务序列为:98,183,37,122,14,124,65,67磁头移动总距离=(98-53)+(183-98)+|37-183|+(122-37)+|14-122|+(124-14)+|65-124|+(67-65)=640(磁道)

2.4.2 SSTF算法分析
磁头当前位于53位置,则:磁头服务序列为:65,67,37,14,98,122,124,183磁头移动总距离=12 + 2 + 30 +23 + 84 + 24 + 2 + 59 = 236 (磁道)

2.4.3 SCAN算法分析
假设磁头当前在53的位置,现在朝0方向移动则:
磁头服务序列为:37,14,65,67,98,122,124,183
磁头移动总距离=16 + 23 + 51 + 2 + 31 + 24 + 2 + 59 = 208 (磁道)

2.4.4 CSCAN算法分析
假设磁头移动的方向是从柱面0到柱面199方向。磁头服务序列为:65,67,98,122,124,183,14,37磁头移动总距离=12 + 2 + 31 + 24 + 2 + 59 + 169 + 23= 322 (磁道)

第3章 总体设计
3.1总体设计流程图

3.2 功能模块分析
3.2.1 二分法排序实现

3.2.2 FCFS算法实现

3.2.3 SSTF算法实现

3.2.3 SCAN算法实现

3.2.4 C-SCAN算法实现

3.2.5 操作界面实现

第4章 功能调试
4.1 实验源码
#include"stdio.h"
#include"stdlib.h"
#define maxsize 1000 //定义最大数组域
void sort(int* a, int left, int right)//二分法排序
{
if (left >= right)/如果左边索引大于或者等于右边的索引就代表已经整理完成一个组了/
{
return;
}
int i = left;
int j = right;
int key = a[left];
while (i < j) /控制在当组内寻找一遍/
{
while (i < j && key <= a[j])//找到从右边开始第一个大于key的值
/而寻找结束的条件就是,1,找到一个小于或者大于key的数(大于或小于取决于你想升
序还是降序)2,没有符合条件1的,并且i与j的大小没有反转
/
{
j–;/向前寻找/
}
a[i] = a[j];
/找到一个这样的数后就把它赋给前面的被拿走的i的值(如果第一次循环且key是
a[left],那么就是给key)
/
while (i < j && key >= a[i])
/这是i在当组内向前寻找,同上,不过注意与key的大小关系停止循环和上面相反,
因为排序思想是把数往两边扔,所以左右两边的数大小与key的关系相反
/
{
i++;
}
a[j] = a[i];
}
a[i] = key;/当在当组内找完一遍以后就把中间数key回归/
sort(a, left, i - 1);/最后用同样的方式对分出来的左边的小组进行同上的做法/
sort(a, i + 1, right);/用同样的方式对分出来的右边的小组进行同上的做法/
/当然最后可能会出现很多分左右,直到每一组的i = j 为止/
}
//先来先服务调度算法
void FIFO(int array[], int m)
{
int sum = 0, j, i, now;
float avg;
printf(“\n 请输入当前的磁道号: “);
scanf_s(”%d”, &now);
printf(“\n FIFO 调度结果: “);
printf(”%d “, now);
for (i = 0; i < m; i++) printf(”%d “, array[i]);
sum = abs(now - array[0]);
for (j = 1; j < m; j++) sum += abs(array[j] - array[j - 1]);//累计总的移动距离
avg = (float)sum / m;//计算平均寻道长度
printf(”\n 移动的总道数: %d \n”, sum);
printf(" 平均寻道长度: %f \n", avg);
}

//最短寻道时间优先算法
void SSTF(int array[], int m)
{
int sum = 0, j, i, now, c = maxsize, k;
int flag[maxsize] = { 0 };
float avg;
printf(“\n 请输入当前的磁道号: “);
scanf_s(”%d”, &now);
printf(“\n SSTF 调度结果: “);
printf(”%d “, now);
for (j = 0; j < m; j++)
{
for (i = 0; i < m; i++)//循环寻找离现在迟道的最小迟道距离
{
if (abs(array[i] - now) < c && flag[i] == 0)
{
k = i;
c = abs(array[i] - now);//迟道距离
}
}
sum += c;
c = maxsize;
printf(”%d “, array[k]);
flag[k] = 1;
now = array[k];
}
printf(”\n 移动的总道数: %d \n”, sum);
avg = (float)sum / m;//计算平均寻道长度
printf(" 平均寻道长度: %f \n", avg);
}

//扫描算法,采用look策略
void SCAN(int array[], int m)
{
int sum = 0, i, now, k;
int flag[maxsize] = { 0 };
float avg;
int array2[maxsize];
for (i = 0; i < m; i++)
{
array2[i] = array[i];
}
sort(array2, 0, m - 1);

printf("\n 请输入当前的磁道号: ");
scanf_s("%d", &now);
printf("\n SCAN 调度结果: ");
printf("%d ", now);
for (i = 0; i < m; i++)//从比现在大的磁道递增开始
{
	if (array2[i] < now)//找出第一个比现磁道大的磁道
	{
		k = i;
		continue;
	}
	sum += array2[i] - now;
	now = array2[i];
	printf("%d ", array2[i]);
}
for (i = k; i >= 0; i--)//从比现在小的磁道递减开始
{
	sum += abs(array2[i] - now);
	now = array2[i];
	printf("%d ", array2[i]);
}
printf("\n 移动的总道数: %d \n", sum);
avg = (float)sum / m;//计算平均寻道长度
printf(" 平均寻道长度: %f \n", avg);

}
//循环扫描算法,采用look策略
void CSCAN(int array[], int m)
{
int sum = 0, i, now, k;
int flag[maxsize] = { 0 };
float avg;
int array2[maxsize];
for (i = 0; i < m; i++)
{
array2[i] = array[i];
}
sort(array2, 0, m - 1);
printf(“\n 请输入当前的磁道号: “);
scanf_s(”%d”, &now);
printf(“\n SCAN 调度结果: “);
printf(”%d “, now);
for (i = 0; i < m; i++)
{
if (array2[i] < now)
{
k = i;
continue;
}
sum += array2[i] - now;
now = array2[i];
printf(”%d “, array2[i]);
}
for (i = 0; i <= k; i++)//从比现在小的磁道递增开始
{
sum += abs(array2[i] - now);
now = array2[i];
printf(”%d “, array2[i]);
}
printf(”\n 移动的总道数: %d \n”, sum);
avg = (float)sum / m;//计算平均寻道长度
printf(" 平均寻道长度: %f \n", avg);
}

// 操作界面
int main()
{
int c;
int count;
//int m=0;
int cidao[maxsize];//定义磁道号数组
int i = 0;
int b;
printf(“\n --------------------------------------------------\n”);
printf(" 磁盘调度算法模拟");
printf(“\n --------------------------------------------------\n\n”);
printf(“----请先输入磁道数量:------- \n”);
scanf_s(“%d”, &b);
printf(“----请先输入磁道序列:------- \n”);
for (i = 0; i < b; i++) {
scanf_s(“%d”, &cidao[i]);
}
printf(“\n 磁道读取结果: \n”);
for (i = 0; i < b; i++)
{
printf(“%d “, cidao[i]);//输出读取的磁道的磁道号
}
count = b;
printf(”\n “);
while (1)
{
printf(”\n -----------------------------------\n”);
printf(" 算法选择 \n");
printf(" -----------------------------------\n");
printf(“|1、先进先出算法(FIFO) | \n”);
printf(“|2、最短服务时间优先算法(SSTF) |\n”);
printf(“|3、扫描算法(SCAN)(LOOK策略) |\n”);
printf(“|4、循环扫描算法(C-SCAN)(LOOK策略)|\n”);
printf(“|5. 退出 |\n”);
printf(" -----------------------------------\n");
printf(“\n”);
printf(“请选择你想要操作的算法编号(输入数字1-4): “);
scanf_s(”%d”, &c);
if (c > 7)
break;
switch ©//算法选择
{
case 1:
FIFO(cidao, count);//先进先出算法
printf(“\n”);
break;
case 2:
SSTF(cidao, count);//最短服务时间优先算法
printf(“\n”);
break;
case 3:
SCAN(cidao, count);//扫描算法,采用look策略
printf(“\n”);
break;
case 4:
CSCAN(cidao, count);//循环扫描算法,采用look策略
printf(“\n”);
break;
case 5:
exit(0);
}
}
return 0;
}
4.2 实验调试结果
4.2.1 FIFO

4.2.2 SSTF

4.2.3 SCAN

4.2.4 C-SCAN

4.2.5 退出

第5章 总结
磁盘调度算法,目的是为了让我们观察,体会操作系统充磁盘调度的方法。要做出实验首先要了解算法的过程,最短寻道算法(sstf)就是总会从等待访问者中挑选寻找时间最短的那个请求先执行的,无论是在磁盘的里面还是外面,只要离他近的就先执行。而循环扫描算法就和我们平时坐的电梯有点类似,先往一个方向运行。这次的实验里对总道数的计算一开始理解的不够全,尤其是循环扫描算法。但用电梯实例来想象模拟后我很快弄明白了怎么回事。但是程序仍然有很多改进的地方,资源可以更加节约,算法也还有优化的余地,但是时间和精力有限,我会在课余的时间加深对磁盘调度的理解同时如上其他的算法,例如扫描调度(SCAN)算法,先来先服务(FCFS)等。这次实验也让我感觉到了算法才是程序的灵魂,没有好的算法就像巧妇难为无米之炊,即使有再好的工具和基本功没有算法 和基本思想也是不可行的。

磁盘调度算法

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值