磁盘调度算法-广工操作系统课程设计

课程设计

课程名称操作系统

题目名称磁盘调度算法

学生学院计算机学院

专业班级2010级计算机科学与技术四班学号3110006015

学生姓名张法光

指导教师______何翠红_________ 2013 年1 月 13 日

操作系统课程设计任务书

说明:本表由指导教师填写,由系主任审核后下达给选题学生,装订在设计(论文)首页

目录

一、设计思想说明 (7)

1.1 设计环境 (7)

1.2 设计思想 (7)

二、系统结构 (7)

三、数据结构的说明 (7)

四、算法流程图 (8)

1.先来先服务算法(FCFS) (9)

2.最短寻道时间优先调度算法(SSTF) (10)

3.扫描算法(SCAN) (11)

4.循环扫描算法(CSCAN) (12)

五、主要函数列表 (12)

六、测试与分析 (13)

七、用户使用说明 (20)

八、心得体会 (20)

九、附录 (20)

正文

1设计思想说明

1.1 设计环境

硬件环境:CPU (英特尔)Intel(R) Core(TM) i3-2310M CPU @ 2.10GHz(2100 Mhz) 内存 4.00 GB (1334 MHz) 硬盘5400转500G

软件环境:Windows 7 SP1, V isual C++ 6.0

1.2 设计思想

1.先到先服务算法(FCFS)

这是一种比较简单的磁盘调度算法。它根据进程请求访问磁盘的先后次序进行调度。此算法的优点是公平、简单,且每个进程的请求都能依次得到处理,不会出现某一进程的请求长期得不到满足的情况。此算法由于未对寻道进行优化,在对磁盘的访问请求比较多的情况下,此算法将降低设备服务的吞吐量,致使平均寻道时间可能较长,但各进程得到服务的响应时间的变化幅度较小。

2.最短寻道时间优先调度算法(SSTF)

该算法选择这样的进程,其要求访问的磁道与当前磁头所在的磁道距离最近,以使每次的寻道时间最短,该算法可以得到比较好的吞吐量,但却不能保证平均寻道时间最短。其缺点是对用户的服务请求的响应机会不是均等的,因而导致响应时间的变化幅度很大。在服务请求很多的情况下,对内外边缘磁道的请求将会无限期的被延迟,有些请求的响应时间将不可预期。

3.扫描算法(SCAN)

扫描算法不仅考虑到欲访问的磁道与当前磁道的距离,更优先考虑的是磁头的当前移动方向。例如,当磁头正在自里向外移动时,扫描算法所选择的下一个访问对象应是其欲访问的磁道既在当前磁道之外,又是距离最近的。这样自里向外地访问,直到再无更外的磁道需要访问才将磁臂换向,自外向里移动。这时,同样也是每次选择这样的进程来调度,即其要访问的磁道,在当前磁道之内,从而避免了饥饿现象的出现。由于这种算法中磁头移动的规律颇似电梯的运行,故又称为电梯调度算法。此算法基本上克服了最短寻道时间优先算法的服务集中于中间磁道和响应时间变化比较大的缺点,而具有最短寻道时间优先算法的优点即吞吐量较大,平均响应时间较小,但由于是摆动式的扫描方法,两侧磁道被访问的频率仍低于中间磁道。

4.循环扫描(CSACN)

循环扫描算法是对扫描算法的改进。如果对磁道的访问请求是均匀分布的,当磁头到达磁盘的一端,并反向运动时落在磁头之后的访问请求相对较少。这是由于这些磁道刚被处理,而磁盘另一端的请求密度相当高,且这些访问请求等待的时间较长,为了解决这种情况,循环扫描算法规定磁头单向移动。例如,只自里向外移动,当磁头移到最外的被访问磁道时,磁头立即返回到最里的欲访磁道,即将最小磁道号紧接着最大磁道号构成循环,进行扫描。

2系统结构

本系统划分为五个模块:

1.冒泡排序算法模块:void sort(int array[],int m)

2.先来先服务算法模块:void FCFS(int array[],int m)

3.最短寻道时间优先算法模块:void SSTF(int array[],int m)

4.扫描算法模块:void SCAN(int array[],int m)

5.循环扫描算法模块:void CSCAN(int array[],int m)

系统结构图:

3数据结构的说明

k:递增变量,为l,r赋值。

now:用于记录当前磁道号

l:用于记录k的左邻位置

r:用于k的位置

array[]:放置磁道号的数组;

4算法流程图

1.先来先服务算法(FCFS)流程图:

2.最短寻道时间优先算法(SSTF)流程图:

3.扫描算法(SCAN)流程图:

4..循环扫描算法(CSCAN)流程图:

5 主要函数列表

6 测试与分析

首先从test.txt文本读取测试磁道号序列:90 58 55 39 38 18 150 160 184

开始测试:

1 先来先服务算法

2 最短寻道时间优先算法

(1)当前磁道号大于磁道序列中的最大的磁道号时

(2)当前磁道号小于磁道序列中的最小的磁道号时

(3)当前磁道号大于磁道序列中的最小的磁道号且小于最大磁道号时

3 扫描算法

(1)当前磁道号大于磁道序列中的最大的磁道号时

(2)当前磁道号小于磁道序列中的最小的磁道号时

(3)当前磁道号大于磁道序列中的最小的磁道号且小于最大磁道号(磁头向外)时

(4)当前磁道号大于磁道序列中的最小的磁道号且小于最大磁道号(磁头向内)时

4 循环扫描算法

(1)当前磁道号大于磁道序列中的最大的磁道号时

(2)当前磁道号小于磁道序列中的最小的磁道号时

(3)当前磁道号大于磁道序列中的最小的磁道号且小于最大磁道号(磁头向外)时

(4)当前磁道号大于磁道序列中的最小的磁道号且小于最大磁道号(磁头向内)时

关于测试结果的对比分析:

7 用户使用说明

用户使用时请注意:

1、进入系统前,先到源程序目录下的text.txt设置好磁道号序列;

2、系统输出你输入的磁道序列,用户核对输入数据;

3、系统显示系统算法菜单;

4、用户选择相应算法,回车;

5、系统要求输入当前磁道号,用户输入磁道号,回车;

6、系统输出磁头的扫描序列和平均寻道长度;

7、用户继续选择系统菜单中的算法;

8、当用户选择扫描算法时,需要输入当前移动臂的移动的方向,其中1 表示向磁道号增加方向访问,0磁道号减小方向访问。

8 心得体会

本次课程设计主要是理解四种磁盘调度的工作原理。在课程设计前的准备工作时,先划分好各功能模块,再逐步实现。先到先服务算法是最简单也是最基本的磁盘调度算法。最短寻道时间优先算法则是扫描算法和循环算法的基础,后者是继承与发展。起初做最短寻道时间优先算法,漏掉了当前磁道号大于数组边界的情况,通过画设计稿图,理清了思路后重新调试并最终实现了SSTF算法。SCAN和CSCAN算法主要在于对方向的把握,弄清楚移动方向就基本大功告成了。最后是主函数的调用,利用C语言的fopen函数来获取文本中的测试数据库。避免了手动输入的带来的不便性和输入错误。很高兴能在有限的时间内完成了磁盘调度算法系统课程设计和程序开发,今后将仍会继续努力学习操作系统,定期实践开发工作。

9 附录

带注释的源程序。如果提交源程序软盘,可以只列出程序文件名清单。

//源程序

#include"stdio.h"

#include"stdlib.h"

#include"math.h"

#define maxsize 100 //定义最大数组域

//冒泡排序算法

void sort(int array[],int m)

{

int i,j;int temp;

for(i=0;i

{

for(j=i+1;j

{

if(array[i]>array[j])//两磁道号之间比较

{

temp=array[i];

array[i]=array[j];

array[j]=temp;

}

}

}

for( i=0;i

{

printf("%d ",array[i]);

}

}

//先来先服务调度算法(FCFS)

void FCFS(int array[],int m)

{

int sum=0,j,i;

int avg;

printf("\n FCFS调度结果: ");

for(i=0;i

{

printf("%d ",array[i]);

}

for(i=0,j=1;j

{

sum+=abs(array[j]-array[i]);//总的移动距离,通过累加差值的绝对值}

avg=sum/(m-1);//计算平均寻道长度

printf("\n 移动的总道数: %d \n",sum);

printf(" 平均寻道长度: %d \n",avg);

}

//最短寻道时间优先调度算法(SSTF)

void SSTF(int array[],int m)

{

int k=1;//递增变量

int now; //用于记录当前磁道号

int l,r;//l,r分别用于记录k的左邻位置和k的位置

int i,j,sum=0;

int avg;

sort(array,m); //调用冒泡排序sort对磁道号排序并输出

printf("\n 请输入当前的磁道号:");

scanf("%d",&now);

printf("\n SSTF调度结果: ");

if(array[m-1]<=now)//若当前磁道号大于数组的最大值,即当前磁道号大于待访问的全部磁道号

{

for(i=m-1;i>=0;i--)//将数组磁道号从大到小输出

printf("%d ",array[i]);

sum=now-array[0];//计算移动距离,磁道号为升序序列,故sum值为磁道号首尾差

}

else if(array[0]>=now)//若当前磁道号小于数组的最小值,即当前磁道号小于待访问的全部磁道号

{

for(i=0;i

printf("%d ",array[i]);

sum=array[m-1]-now;//计算移动距离,磁道号为升序序列,故sum值为磁道号首尾差

}

else //now大小处于数组元素之间

{

while(array[k]

{

k++;//确定当前磁道在磁盘号的升序序列的位置

}

//该WHILE语句运行完后,此时array[l]

l=k-1;//l用于记录k的左邻位置

r=k; //r用于记录k的位置

while((l>=0)&&(r

{

if((now-array[l])<=(array[r]-now))//说明:判断当前磁盘号与谁更近

{ //判断:此时左邻磁盘号l与当前磁盘号更接近 printf("%d ",array[l]);

sum+=now-array[l];//计算移动距离,即左邻磁盘号l到当前磁盘号的距离

now=array[l];//传递新的当前磁盘号

l=l-1;//此后逐级向左移动

}

else //说明:判断当前磁盘号与谁更近

{ //判断:此时r与当前磁盘号更接近

printf("%d ",array[r]);

sum+=array[r]-now;//计算移动距离

now=array[r];//传递新的当前磁盘号

r=r+1;//此后逐级向右移动

}

}

if(l=-1) //l=-1时达到最左端的情况

{

for(j=r;j

{

printf("%d ",array[j]);

}

sum+=array[m-1]-array[0];//计算移动距离

}

else //r=m时达到最右端的情况

{

for(j=l;j>=0;j--) //依次输出磁盘号

{

printf("%d ",array[j]);

}

sum+=array[m-1]-array[0];//计算移动距离

}

}

avg=sum/m;

printf("\n 移动的总道数: %d \n",sum);

printf(" 平均寻道长度: %d \n",avg);

}

//扫描算法(SCAN)

void SCAN(int array[],int m)//需给出当前磁道号和移动臂的移动方向{

int k=1;//递增变量

int now;//用于记录当前磁道号

int l,r;//l,r分别用于记录k的左邻位置和k的位置

int d;//当前移动臂的移动的方向,1表示增加方向,2表示递减方向

int i,j,sum=0;

相关主题
相关文档
最新文档