实验七 磁盘调度算法的模拟与实现
完整课程设计源码及其报告查看:陈陈的操作系统课程设计
1、实验目的
(1) 了解磁盘结构以及磁盘上数据的组织方式。
(2) 掌握磁盘访问时间的计算方式。
(3) 掌握常用磁盘调度算法及其相关特性。
2、实验基本知识及原理
(1)磁盘数据的组织
磁盘上每一条物理记录都有唯一的地址,该地址包括三个部分:磁头号(盘面号)、柱面号(磁
道号)和扇区号。给定这三个量就可以唯一地确定一个地址。
(2)磁盘访问时间的计算方式
磁盘在工作时以恒定的速率旋转。为保证读或写,磁头必须移动到所要求的磁道上,当所要求
的扇区的开始位置旋转到磁头下时,开始读或写数据。对磁盘的访问时间包括:寻道时间、旋转延
迟时间和传输时间。
(3)磁盘调度算法
磁盘调度的目的是要尽可能降低磁盘的寻道时间,以提高磁盘 I/O 系统的性能。
先进先出算法FIFO:按访问请求到达的先后次序进行调度。
最短服务时间优先算法SSTF:优先选择使磁头臂从当前位置开始移动最少的磁盘 I/O 请求进行调度。
SCAN(电梯算法):要求磁头臂先沿一个方向移动,并在途中满足所有未完成的请求,直到它到达这个方向上的最后一个磁道,或者在这个方向上没有别的请求为止,后一种改进有时候称作LOOK 策略。然后倒转服务方向,沿相反方向扫描,同样按顺序完成所有请求。
C-SCAN(循环扫描)算法:在磁盘调度时,把扫描限定在一个方向,当沿某个方向访问到最后一个磁道时,磁头臂返回到磁盘的另一端,并再次开始扫描。
3、实验内容
本实验通过编程模拟实现几种常见的磁盘调度算法。
(1)测试数据:参见教材 P305,测试结果参见表 11.2。
(2)使用 C 语言编程实现 FIFO、SSTF、SCAN、C-SCAN 算法。
4、 实验结果与分析
5、 实验总结
实验源码如下:
#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("%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("%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("%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("%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("%d",&b);printf("----请先输入磁道序列:------- \n");for(i=0;i<b;i++){scanf("%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("%d",&c);if(c>7)break;switch(c)//算法选择{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;}
实验结果截图分析:
更多课程设计源码请进主页查看搜索:陈陈不会敲代码
完整课程设计报告请下载:陈陈的操作系统课程设计源码及其报告
完整报告包含以下内容的源码以及实验报告:
资源展示如下: