模拟磁盘调度 课程设计(操作系统 C语言)

(乾坤未定,你我皆是黑马!)       

       期末用了大概一周的时间完成了操作系统的课程设计,本来是随便选的一个题目,(因为上课的时候隐隐约约有点印象)然后仔细研究一下发现里面的算法还是挺简单的!然后额外加了一些附加的功能。算法实现基本先要了解四种算法的调度方式然后重新排序生成访问磁道的顺序(主要用冒泡排序)即可。

首先了解一下这几种算法

1、先来先服务算法(FCFS)First Come First Service

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

2、最短寻道时间优先算法(SSTF) Shortest Seek Time First

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

3、扫描算法(SCAN)

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

4、循环扫描算法(CSCAN)

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

 

 

 

先介绍一下这四种算法我的实现思路:(首先设置开始磁道位置)

先来先服务:按照输入的磁道顺序直接访问,记录下每一个磁道的寻道的地址。

最短寻道:对访问顺序进行排序,先找到距离开始磁道最近的磁道,然后把用该磁道的位置替换成开始磁道,之后遍历寻找剩余位置中距离开始磁道最近的位置(开始磁道已经被上一次替换),重新生成访问顺序。

扫描算法:也叫电梯算法,首先把要访问的数组,分成两个数组,一个全部比开始位置小的,一个全部比开始位置大的,然后新建一个数组利用这两个数组重新在新数组里面排序。根据扫描方式,很好理解的。

循环扫描算法:这个算法和扫描算法很类似,只是排序方式不同,从内向外排序之后,把另一串数组按照从小到大接在新数组后面,组件的方法大概和扫描算法类似。

 

 

1.功能界面:

2.创建磁道

3.先来先服务算法

4.最短寻道算法

5.扫描算法

6.循环扫描

7.算法优劣比较

 

8.退出

 

详细代码在这里~可以留着参考   (点个关注再走呗!

 

/**
   磁盘调度算法3.0 
   制作人:图南
**/ 
#include<stdio.h>

#include<stdlib.h>

#include<conio.h>

#include<string.h>

#include<windows.h>

#include <math.h>

#define MAX 200
 

//显示菜单


void MEMU();

void color(int x);

void gotoxy(int a, int b);

void first(); 

void head();

void creat();

void FCFS();

void SSTF();

void SCAN();

void CSAN();

void compare();





  //登陆界面
void first() {

	color(2);

	gotoxy(35, 8);

	printf("磁盘调度3.0");

	color(3);

	gotoxy(38, 14);

    printf("制作人:图南 ");



}

//自定义函根据参数改变颜色

void color(int x)

{
    //参数在0-15的范围颜色
	if (x >= 0 && x <= 15)

          //只有一个参数,改变字体颜色
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), x);

	else
         //默认的颜色白色
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);

}



/************调用函数设置光标位置 ***************/

void gotoxy(int a, int b) {

	int xx = 0x0b;

	HANDLE hOutput;

	COORD loc;

	loc.X = a;

	loc.Y = b;
	
     //获取标准输出的句柄
	hOutput = GetStdHandle(STD_OUTPUT_HANDLE); 

    //设置光标位置
	SetConsoleCursorPosition(hOutput, loc);

	return;

}

//标题显示
void head()

{
	color(10);

	// gotoxy(20,20);

	printf("\t\t\t----------------------------------------\n");

	printf("\t\t\t|     磁     盘     调     度           |\n");
	

	printf("\t\t\t----------------------------------------\n");


}


void MENU(){
 	head();
	printf("\n");
	color(12);

	printf("\t本系统操作功能如下:\n"); 
	
	printf("\t\t\t -----------------------------------------\n");
	printf("\t\t\t|           1.创建磁道     (CREATE)...   |\n"); 
		printf("\t\t\t -----------------------------------------\n");
		printf("\t\t\t|           2.先来先服务  (FCFS)...    |\n"); 
			printf("\t\t\t -----------------------------------------\n");
			printf("\t\t\t|           3.最短寻道    (SSTF)...    |\n"); 
				printf("\t\t\t -----------------------------------------\n");
				printf("\t\t\t|           4.扫描算法    (SCAN)...    |\n"); 
					printf("\t\t\t -----------------------------------------\n");
					printf("\t\t\t|           5.循环扫描算法(CSCAN)...   |\n"); 
						printf("\t\t\t -----------------------------------------\n");
						printf("\t\t\t|           6.算法优劣比较(COMPARE)... |\n"); 
					    	printf("\t\t\t -----------------------------------------\n");
					    	printf("\t\t\t|           7.退出        (EXIT)...    |\n"); 
						    	printf("\t\t\t -----------------------------------------\n");
								printf("\t请选择你要进行的操作::\n");
							
}


void main(){
	
	  
	    
     	first(); 
     	
		gotoxy(25, 25);

	    printf("请点击任意键继续使用。。。");

    	getch();

	     system("cls");
	     int cr=0;
	     

     
     	while(1){
     			MENU();
	    
	     		int choice;
                scanf("%d",&choice);
                
                
               if(cr==0)
                  {
                  	if(choice==1){
                  			printf("现在开始创建!!!\n");
					  }else{
					  	
                  	printf("必须先创建磁道哟!!!\n");
                  	choice=1; 
                  		gotoxy(25, 35);
                  		
                  	  printf("请点击任意键继续使用。。。\n");
                  	  
                   	getch();
                   }
                
				  }
	
     	    
                
  
				  
		switch(choice)
       {
       	    
       
       	case 1:
       		system("cls");
			   creat(); 
			   cr=1;
			   break;
       		
       	case 2:
       		system("cls");
       		FCFS();
       		  printf("请点击任意键继续使用。。。");

    	getch();

	     system("cls");
       		
       		break;
        case 3:
       		system("cls");
       		SSTF();
       		  printf("请点击任意键继续使用。。。");

    	getch();

	     system("cls");
       		break;
        case 4:
       		system("cls");
       		 SCAN();
       		   printf("请点击任意键继续使用。。。");

    	getch();

	     system("cls");
       		 break;
       	case 5:
       		system("cls");
       		 CSAN();
       		   printf("请点击任意键继续使用。。。");

    	getch();

	     system("cls");
       		 break;
       		case 6:
       		system("cls");
       		 compare(); 
    
       		   printf("请点击任意键继续使用。。。");

    	getch();

	     system("cls");
       		 break;
        case 7:
        	printf("再见!Bye~\n"); 
        		color(13);

			gotoxy(25, 25);

			printf("欢迎下次使用,再见!!!!!!");

			exit(1);
        
        	
        default:

			printf("Input error!(输入数字有误,请重新输入))\n");
		 printf("请点击任意键继续使用。。。");

    	getch();

	     system("cls");
	   }
         
          getchar();    
   
     		
		 }
     	
	
	 
		  
	    MENU();
	    
} 

int num,sum,kai,max;
int m=0;
int n=0;
int s[100];    //记录磁盘访问顺序 
int s1[100];  //记录磁盘移动距离 
int c1[50];    //小于开始磁道递减 
int c2[50];     //大于开始磁道递增 
int visit[MAX]; //标记数组 
double arr[4],arr2[4];
double avg1,avg2,avg3,avg4;

    //创建磁道   
void creat()
{
  color(10);
  printf("----------------------------------------------------\n");
  printf("请输入从哪个磁道开始:\t\n");
  printf("----------------------------------------------------\n");
  scanf("%d",&kai);
  printf("----------------------------------------------------\n");
  printf("请输入最长磁道号:\n"); 
  printf("------------------------------------------------------\n");
  scanf("%d",&max); 
  printf("------------------------------------------------------\n");
  printf("请输入磁道的个数:\n");
  printf("------------------------------------------------------\n");
  scanf("%d",&num);
  for(int j=0;j<num;j++)
  {
    printf("请输入第%d个磁道\n",j+1);
   
    scanf("%d",&s[j]);
   
    if(s[j]>max) 

	{

		printf("不可以,你输入的磁道不能超过%d\n",max);
		for(int j=0;j<num;j++){
			s[j]=0;
		}
		break;

	}

}

 color(14);
 
 printf("被访问的下一个磁道\n");
  for(int i=0;i<num;i++)
  {
    printf("%d:\t%d\t\n",i+1,s[i]);
  }
 
 int su=kai;
 int t;
    //比开始磁道小的放入c1  比开始磁道大的放入c2 
 for(int i=0;i<num;i++)
   if(su>s[i])
      c1[m++]=s[i];
      else
      c2[n++]=s[i];
      //按照从大到小的顺序排列 
   for(int i=0;i<m;i++)
        for(int j=i;j<m;j++)
                if(c1[i]<c1[j])
                {
				t=c1[i];
				c1[i]=c1[j];
				c1[j]=t;
				}
	//c2数组按照磁道从小到大的顺序排列 
    for(int i=0;i<n;i++)
        for(int j=i;j<n;j++)
                if(c2[i]>c2[j])
                {
				t=c2[i];
				c2[i]=c2[j];
				c2[j]=t;}
 
}

   //先来先服务算法(FCFS)
void FCFS()
{
  printf("先来先服务 FCFS(从%d号磁道开始)\n",kai);
      printf("----------------------------------------------------\n");
  
  printf("被访问的下一个磁道\t\t\t磁道号移动距离\n");
    int su=kai;
      sum=0;
      for(int i=0;i<num;i++)
      { if(su<s[i])
      s1[i]=s[i]-su;
      else
      s1[i]=su-s[i];
      su=s[i];
      sum+=s1[i];
      }
 
      for(int i=0;i<num;i++)
       {
         printf("\t%d\t\t\t\t\t%d\t\t\n",s[i],s1[i]);
       }
      printf("寻道长度:%d\n",sum);
      avg1=(double)sum/num;
      printf("平均寻道长度:%.2lf\n",avg1); 
     // printf("%f\n",avg1); 
      arr[0]=avg1;
 
}
    //最短寻道时间优先算法(SSTF)
    void SSTF() 
{
	 printf("最短寻道 SSTF(从%d号磁道开始)\n",kai);
      printf("----------------------------------------------------\n");
      printf("被访问的下一个磁道\t\t\t磁道号移动距离\n");
	int k;//记录最近的磁道号 
	int su;
	int shortest;  //记录最短的距离 
	int s2[100];
	memset(visit,1,sizeof(visit));//数组初始化为1 
	su=kai;
	sum=0;
	for(int i=0;i<num;i++){
		shortest=MAX;
		for(int j=0;j<num;j++){  //比较得出最近的磁道 
			if(visit[j]){
				if(fabs(su-s[j])<shortest){
					shortest=fabs(su-s[j]);
					k=j;
				}
					
			}
		} 
	 	s1[i]=shortest;//记录移动的距离 
		su=s[k];  //跟踪当前磁头所在位置 
		visit[k]=0;  //标记已访问 
		s2[i]=s[k];  //记录路径 
	}
      for(int i=0;i<num;i++){
      	sum=s1[i]+sum;
	  }
		
	  for(int i=0;i<num;i++)
       {
         printf("\t%d\t\t\t\t\t%d\t\t\n",s2[i],s1[i]);
       }
       printf("寻道长度:%d\n",sum);
         avg2=(double)sum/num;
        printf("平均寻道长度:%.2lf\n",avg2); 
         arr[1]=avg2;

}
  
    
    //扫描算法(SCAN)电梯调度  
void SCAN()
{
     printf("扫描算法 SCAN(从%d号磁道开始)\n",kai);
     printf("----------------------------------------------------\n");
     printf("被访问的下一个磁道:\t\t\t磁道号移动距离:\n");
      int su=kai;
      int s2[100];
      sum=0;
    //s2排序设置成增加方向访问 
      for(int i=0;i<n;i++)
      s2[i]=c2[i];
      for(int i=0;i<m;i++)
      s2[i+n]=c1[i];
      for(int i=0;i<num;i++)
      { if(su<s2[i])
        s1[i]=s2[i]-su;
        else
        s1[i]=su-s2[i];
        su=s2[i];
        sum+=s1[i];
      }
      for(int i=0;i<num;i++)
       {
         printf("\t%d\t\t\t\t\t%d\t\t\n",s2[i],s1[i]);
       }
       printf("寻道长度:%d\n",sum);
         avg3=(double)sum/num;
        printf("平均寻道长度:%.2lf\n",avg3); 
         arr[2]=avg3;
    }
    
    //循环扫描算法(CSCAN)
void CSAN()
{
     printf("循环扫描 CSAN(从%d号磁道开始)\n",kai);
     printf("----------------------------------------------------\n");
     printf("被访问的下一个磁道:\t\t\t磁道号移动距离:\n");
      int su=kai;
      int j=0;
      int s2[100];
      sum=0;
     //把c2添加到s2中,c1按照相反的顺序添加 
      for(int i=0;i<n;i++)
      s2[i]  =c2[i];
      for(int i=m-1;i>=0;j++,i--)
      s2[j+n]=c1[i];
      for(int i=0;i<num;i++)
      { if(su<s2[i])
        s1[i]=s2[i]-su;
       else
        s1[i]=su-s2[i];
        su=s2[i];
        sum+=s1[i];
      }
      for(int i=0;i<num;i++)
       {printf("\t%d\t\t\t\t\t%d\t\t\n",s2[i],s1[i]);
       }
       printf("寻道长度:%d\n",sum);
       avg4=(double)sum/num;
      printf("平均寻道长度:%.2lf\n",avg4); 
       arr[3]=avg4;
        }
        

     //比较不同算法的优劣
	 void compare(){
	 	color(5); 

		int n;
		int j;
		int i;
		double buf;
		n=4;
	    for (i=0; i<n; ++i)
	    {
	    		arr2[i]=arr[i];
		}
            
		//冒泡排序比较 
		 for (i=0; i<n-1; i++)  
    {
        for (j=0; j<n-1-i; j++)  
        {
            if (arr2[j] > arr2[j+1])
            {
                buf = arr2[j];
                arr2[j] = arr2[j+1];
                arr2[j+1] = buf;
            }
        }
    }
    
  //  printf("磁盘调度算法\t 平均寻道长度\n");
    printf("\t平均寻道长度排序为:"); 
    
	 for (i=0; i<n; ++i)
    {
        printf("\t%.2lf\t", arr2[i]);
    }
    printf("\n"); 
    
    printf("---------------------------------------------------------------\n");
    
       	char a[]="先来先服务算法";
       	
	 	char b[]="最短寻道算法";
	 	
		char c[]="扫描算法";
		
		char d[]="循环扫描算法"; 
		
		printf("\t磁盘调度算法\t 平均寻道长度\n");
		
		printf("\t%s\t %.2lf\n",a,avg1); 
		
			printf("\t%s\t %.2lf\n",b,avg2); 
		
				printf("\t%s\t %.2lf\n",c,avg3); 
	
					printf("\t%s\t %.2lf\n",d,avg4); 
	
					printf("\n");
		 
		
	 } 
	 
	 
	 	
	 

 

 

 

 

 

 

  • 14
    点赞
  • 80
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值