磁盘调度:本实验通过编程模拟实现几种常见的磁盘调度算法。使用 C 语言编程实现 FIFO、SSTF、SCAN、C-SCAN 算法。
#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"); 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(" 1、先进先出算法(FIFO) \n"); printf(" 2、最短服务时间优先算法(SSTF) \n"); printf(" 3、扫描算法(SCAN)(LOOK策略) \n"); printf(" 4、循环扫描算法(C-SCAN)(LOOK策略) \n"); printf(" 5. 退出\n"); printf("\n"); printf("请选择输入菜单中的数字序号进行后续操作: "); 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; }