操作系统 磁盘调度综合算法

来源:互联网 发布:吉他软件电脑版 编辑:程序博客网 时间:2024/05/18 12:32
磁盘调度在多道程序设计的计算机系统中,各个进程可能会不断提出不同的对磁盘进行读/写操作的请求。由于有时候这些进程的发送请求的速度比磁盘响应的还要快,因此我们有必要为每个磁盘设备建立一个等待队列,常用的磁盘调度算法有以下四种:
先来先服务算法(FCFS),
最短寻道时间优先算法(SSTF),
扫描算法(SCAN),
循环扫描算法(CSCAN)


以下代码是对算法的实现:

#include "stdio.h"
#include "stdlib.h"
#include "iostream"
using namespace std;
void Fuzhi(int Sour[],int Dist[] ,int x); //数组Sour复制到数组Dist,复制到x个数
void Dayin(int Pri[],int x);  //打印输出数组Pri
void Yidong(int Sour[],int x,int y);  //数组Sour把x位置的数删除,并把y前面的数向前移动,y后的数保持不变(即会出现2个y) 
void Shuru(int CDH[]);
void FCFS(int Han,int CDH[]);  //先来先服务算法(FCFS)
void SSTF(int Han,int CDH[]);  //最短寻道时间优先算法(SSTF)
int SCAN(int Han,int CDH[],int x,int y);  //扫描算法(SCAN)
void CSCAN(int Han,int CDH[]);  //循环扫描算法(CSCAN)
void PaiXu();  //寻道长度由低到高排序
void Pri();
int NAll=0;
int Best[5][2]; //用作寻道长度由低到高排序时存放的数组 
int Limit=0; //输入寻找的范围磁道数i
int Jage;
int Min=16383; 
float Aver=0;




int main()
{
 int i;
 int SJCDH[10];  //声明准备要生成的随机磁道号的数组
 int CDS;  //磁道数
 int Con=1;
 int n;
 int an=0;
 system("color 27"); 
 while(Con==1)
 {
  Jage=0;
  printf("\n 请输入初始的磁道数(0<n<16383):");
     scanf("%d",&CDS);
   printf("\n 输入寻找的范围:");
  scanf("%d",&Limit);
  if(Limit>16383){
   printf("超出范围!");
  } 
  else{
printf("\n                  磁盘调度算法                      \n");
    printf("             1.先来先服务算法(FCFS)                      \n");
    printf("              2.最短寻道时间优先算法(SSTF)                \n");
    printf("              3.扫描算法(SCAN)                           \n");
    printf("              4.循环扫描算法(CSCAN)                      \n");
printf("              5.四种方法以及平均寻道数                    \n");
printf("              6.退出                    \n");
  printf(" 请选择:");
 scanf("%d",&n);
 if(n==0) exit(0);
 printf("\n");
 switch(n)
 {
 case 1:
  
  Shuru(SJCDH);  //随机生成磁道数
  FCFS(CDS,SJCDH); //先来先服务算法(FCFS)
  break;
 case 2:
  Shuru(SJCDH);  //随机生成磁道数
  SSTF(CDS,SJCDH); //最短寻道时间优先算法(SSTF)
  break;
 case 3:
  Shuru(SJCDH);  //随机生成磁道数
  SCAN(CDS,SJCDH,0,9);  //扫描算法(SCAN)
  break;
 case 4:
  Shuru(SJCDH);  //随机生成磁道数
  CSCAN(CDS,SJCDH); //循环扫描算法(CSCAN)   
  break;
 case 5:
  Shuru(SJCDH);  //随机生成磁道数
  FCFS(CDS,SJCDH); //先来先服务算法(FCFS)
  SSTF(CDS,SJCDH); //最短寻道时间优先算法(SSTF)
  SCAN(CDS,SJCDH,0,9); //扫描算法(SCAN)
  CSCAN(CDS,SJCDH);  //循环扫描算法(CSCAN)
  PaiXu();  //寻道长度由低到高排序
  printf("\n\n 寻道长度由低到高排序:"); 
  for(i=0;i<5;i++)
  {
  if(Best[i][0]!=0) 
   printf("%4d ",Best[i][0]);
  }
  break;
 }
  printf("\n\n 是否继续(按0结束,按1继续)?");
  scanf("%5d",&Con);
  }


  }
}




void Fuzhi(int Sour[],int Dist[] ,int x)
{
 int i;
 for(i=0;i<=x;i++)
 {
  Dist[i]=Sour[i];
 }
}


void Dayin(int Pri[],int x)
{
 int i;
 for(i=0;i<=x;i++)
 {
  printf("%5d",Pri[i]);
 }
}






void Shuru(int CDH[])
{
int i,t,Con;
printf("             1.自动生成磁道数组\n");
printf("             2.手动输入磁道数组(请输入十个数字)\n");
printf(" 请选择:"); 
scanf("%d",&t);
switch(t)
{
case 1:{
for(i=0;i<=9;i++)
   {
  CDH[i]=rand()%Limit;//随机生成10个磁道号
}
printf(" 需要寻找的磁道号:");
Dayin(CDH,9);  //输出随机生成的磁道号
printf("\n");
   break;
}
case 2:{
printf(" 请输入并以空格隔开:");
for(i=0;i<=9;i++)
{
scanf("%d",&CDH[i]);
}
printf(" 需要寻找的磁道号:");
Dayin(CDH,9);  //输出随机生成的磁道号
printf("\n");
break;
}

}



void Yidong(int Sour[],int x,int y)
{
 int i;
 for(i=x;i<y;i++)
 { 
  Sour[i]=Sour[i+1];
  x++;
 }
}
//先来先服务算法(FCFS)
void FCFS(int Han,int CDH[])
{
 int LSSZ[10];  //将随机生成的磁道数数组CDH[]复制给数组LSSZ[]
 int i,k,All,Temp;  //Temp是计算移动的磁道距离的临时变量
 All=0;  //统计全部的磁道数变量
 k=9;  //限定10个的磁道数
 Fuzhi(CDH,LSSZ,9);  //复制磁道号到临时数组LSSZ
    printf("\n 按照FCFS算法磁道的访问顺序为:");
 All=Han-LSSZ[0];
 for(i=0;i<=9;i++)
 {
  Temp=LSSZ[0]-LSSZ[1];//求出移动磁道数,前一个磁道数减去后一个磁道数得出临时的移动距离
  if(Temp<0) 
   Temp=(-Temp);//移动磁道数为负数时,算出相反数作为移动磁道数
  printf("%5d",LSSZ[0]);
  All=Temp+All;//求全部磁道数的总和 
  Yidong(LSSZ,0,k);//每个磁道数向前移动一位
  k--;
 }
 Best[Jage][1]=All;//Best[][1]存放移动磁道数 
 Best[Jage][0]=1; //Best[][0]存放算法的序号为:1 
 Jage++;//排序的序号加1
 Aver=((float) All)/10;//求平均寻道次数 
 printf("\n 移动磁道数:%5d ",All);
 printf("\n 平均寻道长度:%0.2f ",Aver);
}
//最短寻道时间优先算法(SSTF)
void SSTF(int Han,int CDH[])
{
 int i,j,k,h,All;
 int Temp;  //Temp是计算移动的磁道距离的临时变量
 int LSSZ[10];   //将随机生成的磁道数数组CDH[]复制给数组LSSZ[]
 int Min;
 All=0;  //统计全部的磁道数变量
 k=9;  //限定10个的磁道数
 Fuzhi(CDH,LSSZ,9);  //复制磁道号到临时数组LSSZ
    printf("\n 按照SSTF算法磁道的访问顺序为:");
 for(i=0;i<=9;i++)
 {
        Min=64000;
  for(j=0;j<=k;j++) //内循环寻找与当前磁道号最短寻道的时间的磁道号 
  {
   if(LSSZ[j]>Han)  //如果第一个随机生成的磁道号大于当前的磁道号,执行下一句
    Temp=LSSZ[j]-Han;  //求出临时的移动距离
   else
    Temp=Han-LSSZ[j];  //求出临时的移动距离
   if(Temp<Min)  //如果每求出一次的移动距离小于Min,执行下一句
   {
    Min=Temp;  //Temp临时值赋予Min
    h=j;  //把最近当前磁道号的数组下标赋予h
   }
  }
  All=All+Min;  //统计一共移动的距离
  printf("%5d",LSSZ[h]);
  Han=LSSZ[h];  
  Yidong(LSSZ,h,k);  //每个磁道数向前移动一位
  k--;
 }
 Best[Jage][1]=All;//Best[][1]存放移动磁道数 
 Best[Jage][0]=2;//Best[][0]存放算法的序号为:2
 Jage++;//排序序号加1
 Aver=((float)All)/10;//求平均寻道次数 
 printf("\n 移动磁道数:%5d ",All);
 printf("\n 平均寻道长度:%0.2f ",Aver);
}




//扫描算法(SCAN)
int SCAN(int Han,int CDH[],int x,int y)
{
 int j,n,k,h,m,All;
 int t=0;
 int Temp;
 int Min;
 int LSSZ[10]; //将随机生成的磁道数数组CDH[]复制给数组LSSZ[] 
 int Order;
 Order=1;
 k=y;
 m=2;  //控制while语句的执行,即是一定要使当前磁道向内向外都要扫描到
 All=0;  //统计全部的磁道数变量
 Fuzhi(CDH,LSSZ,9);  //复制磁道号到临时数组LSSZ
    printf("\n 按照SCAN算法磁道的访问顺序为:");
 Min=16383; 
 for(j=x;j<=y;j++)  //寻找与当前磁道号最短寻道的时间的磁道号
 {
  if(LSSZ[j]>Han)  //如果第一个随机生成的磁道号大于当前的磁道号,执行下一句
   Temp=LSSZ[j]-Han;  //求出临时的移动距离
  else
   Temp=Han-LSSZ[j];  //求出临时的移动距离
  if(Temp<Min)
  {
   Min=Temp;  //Temp临时值赋予Min
   h=j;   //把最近当前磁道号的数组下标赋予h
  }
 }
 All=All+Min;  
    printf("%5d",LSSZ[h]);
 if(LSSZ[h]>=Han){  //判断磁道的移动方向,即是由里向外还是由外向里
  Order=0;
  t=1;
 }
 Han=LSSZ[h];
 Yidong(LSSZ,h,k);  //每个磁道数向前移动一位
 k--;
 while(m>0)  
 {
  if(Order==1)  //order是判断磁盘扫描的方向标签,order是1的话,磁道向内移动
 {
   for(j=x;j<=y;j++)  
   {
    h=-1;
    Min=16383;
    for(n=x;n<=k;n++)  //判断离当前磁道最近的磁道号
    {
     if(LSSZ[n]<=Han)
     {
      Temp=Han-LSSZ[n];
                if(Temp<Min)
      {
       Min=Temp;  //Temp临时值赋予Min
                h=n;  //把最近当前磁道号的数组下标赋予h
      }
     }
    }
    if(h!=-1)
    {
     All=All+Min;  //叠加移动距离
     printf("%5d",LSSZ[h]);
     Han=LSSZ[h]; //最近的磁道号作为当前磁道
     Yidong(LSSZ,h,k);
     k--;
    }
   }
   Order=0;  //当完成向内的移动,order赋予0,执行else语句,使磁道向外移动
      m--;  //向内完成一次,m减一次,保证while循环执行两次
  }
  else  //order是0的话,磁道向外移动
  {
   for(j=x;j<=y;j++)
   {
    h=-1;
    Min=16383;
    for(n=x;n<=k;n++)  //判断离当前磁道最近的磁道号
    {
     if(LSSZ[n]>=Han)
     {
      Temp=LSSZ[n]-Han;
                if(Temp<Min)
      {
       Min=Temp;   //Temp临时值赋予Min
                   h=n;  //把最近当前磁道号的数组下标赋予h
      }
     }
    }
    if(h!=-1)
    {
     All=All+Min;  //叠加移动距离
     printf("%5d",LSSZ[h]);
     Han=LSSZ[h];  //最近的磁道号作为当前磁道
     Yidong(LSSZ,h,k);
     k--;
    }
   }
   Order=1;  //当完成向内的移动,order赋予0,执行else语句,使磁道向外移动
      m--;   //向内完成一次,m减一次,保证while循环执行两次
  }
 }
 NAll=NAll+All;
 if((y-x)>5)
 {
  Best[Jage][1]=All;//Best[][1]存放移动磁道数 
  Best[Jage][0]=3;//Best[][0]存放算法的序号为:3
  Jage++;//排序序号加1
  Aver=((float)All)/10;//求平均寻道次数 
  printf("\n 移动磁道数:%5d ",All);
  printf("\n 平均寻道长度:%0.2f ",Aver);
 }
 if(t==1) printf("\n 磁道由内向外移动");
 else printf("\n 磁道由外向内移动");
 return(Han);
}
//循环扫描算法(CSCAN)
void CSCAN(int Han,int CDH[])
{


 int j,h,n,Temp,m,k,All,Last,i;
 int LSSZ[10];  //将随机生成的磁道数数组CDH[]复制给数组LSSZ[] 
 int tmp=0;
 m=2;
 k=9;
 All=0;   //统计全部的磁道数变量
 Last=Han;
 Fuzhi(CDH,LSSZ,9);  //复制磁道号到临时数组LSSZ
    printf("\n 按照CSCAN算法磁道的访问顺序为:");
 while(k>=0)
 {
  for(j=0;j<=9;j++)  //从当前磁道号开始,由内向外搜索离当前磁道最近的磁道号
  {
   h=-1;
   Min=16383;
   for(n=0;n<=k;n++)
   {
    if(LSSZ[n]>=Han)
    {
     Temp=LSSZ[n]-Han;
            if(Temp<Min)
     {
      Min=Temp;
      h=n;
     }
    }
   }
   if(h!=-1)
   {
    All=All+Min;  //统计一共移动的距离
    printf("%5d",LSSZ[h]);
    Han=LSSZ[h];
    Last=LSSZ[h];
    Yidong(LSSZ,h,k);
    k--;
   }
  }
  if(k>=0)
  { tmp=LSSZ[0];
   for(i=0;i<k;i++)//算出剩下磁道号的最小值
   { 
    if(tmp>LSSZ[i]) tmp=LSSZ[i];
     }
   Han=tmp;//把最小的磁道号赋给Han
   Temp=Last-tmp;//求出最大磁道号和最小磁道号的距离差
   All=All+Temp;
  }
 }
 Best[Jage][1]=All;//Best[][1]存放移动磁道数 
 Best[Jage][0]=4;//Best[][0]存放算法的序号为:4
 Jage++;//排序序号加1
 Aver=((float)All)/10;//求平均寻道次数 
 printf("\n 移动磁道数:%5d ",All);
 printf("\n 平均寻道长度:%0.2f ",Aver);
}


void PaiXu()
{
 int i,j,Temp;
 for(i=0;i<5;i++)
 {
  for(j=0;j<4;j++)
  {
   if(Best[j][1]>Best[j+1][1])  //如果前一个算法的移动磁道距离大于后一个移动磁道数,执行下面语句
   {
    Temp=Best[j+1][1];    //从这起下三行执行冒泡法将移动距离大小排序,排完后则执行每个算法的排序
    Best[j+1][1]=Best[j][1];
    Best[j][1]=Temp;
    Temp=Best[j+1][0];  //将每个算法的序号用冒泡法排序
    Best[j+1][0]=Best[j][0];
    Best[j][0]=Temp;
   }
  }
 }
}


原创粉丝点击