(C语言实现)磁盘调度——扫描寻道算法(SCAN)

操作系统实习 专栏收录该内容
6 篇文章 0 订阅

一、设计目的:    

   加深对请求磁盘调度管理实现原理的理解,掌握磁盘调度算法中的扫描寻道算法。

二、设计内容

通过编程实现磁盘调度中扫描寻道算法。
设定开始磁道号寻道范围,依据起始扫描磁道号和最大磁道号数,随机产生要进行寻道的磁道号序列。选择磁盘调度算法,显示该算法的磁道访问顺序,计算出移动的磁道总数和平均寻道总数。

扫描算法SCAN:该算法不仅考虑到欲访问的磁道与当前磁道间的距离,更优先考虑的是磁头当前的移动方向。例如,当磁头正在自里向外移动时,SCAN算法所考虑的下一个访问对象,应是其欲访问的磁道既在当前磁道之外,又是距离最近的。这样自里向外地访问,直至再无更外的磁道需要访问时,才将磁臂换向为自外向里移动。

三、程序结构:

首先,用srand()和rand()函数分别进行初始化、随机数定义和产生互不相同的磁道号序列;
接着,对所有磁道序列降序排序;
然后,找到访问的第一个磁道,必一一访问所有的磁道;

最后,显示该算法的磁道访问顺序,计算出移动的磁道总数和平均寻道总数。

源程序:

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define N 51
struct TCB     //track control block
{
	int tn; //track number磁道号 
	int flag;  //完成标志   flag=-1没完成 flag=1完成 
}track[N]; 

int randomnumber(int n,int max,int min)   //各磁道互不相同 
{
	srand((int)time(NULL));
	int t;   //用来判断这个随机数是否重复
	int x,y;
	for(x=1;x<=n;)
	{
		t=rand()%(max-min+1)+min;
		for(y=1;y<x;y++)
			{if(track[y].tn==t) break;}
		if(y==x) //不重复
		{track[x++].tn=t;track[--x].flag=-1;x++;}//有进程的为-1,没有的为0 (系统初始化) 
	}
}

int SCAN(int n,int present,int max,int min,int option)
{
	int i,j;
	int z=1;
	int start;  //存放磁头访问开始位置 
	int sum=0;  //磁头移动总数 
	for(i=1;i<n;i++)    //对磁道从小到大排序 
	for(j=i+1;j<=n;j++)
	if(track[i].tn>track[j].tn)
	{
	track[0].tn=track[i].tn;
	track[i].tn=track[j].tn;
	track[j].tn=track[0].tn;
	}
	
	if(present<=track[1].tn) start=1;   //找分断点和访问开始位置 
	else if(present>=track[n].tn) start=n;
	else
	{ 
		for(i=2;i<n;i++)
		if(track[i-1].tn<present&&track[i+1].tn>present)
	         {start=i;break;} 
	    if(track[start].tn==present) start=i;
	    else if(track[start].tn<=present)
	    {
	    	if(option==1) start=i+1;
	    	else if(option==0) start=i;
		}
		else if(track[start].tn>=present)
		{
			if(option==1) start=i;
	    	else if(option==0) start=i-1;
		}
	}
	
	//找到磁头访问开始位置后,就是扫描访问各磁道 
	printf("\n\n\n磁道访问顺序:");
	if(start==1||start==n)   
	{
		
		if(start==1)
			for(j=1;j<=n;j++)
				{printf("%d ",track[j].tn); sum+=abs(present-track[j].tn); present=track[j].tn;}
		else if(start==n)
			for(j=n;j>=1;j--)
				{printf("%d ",track[j].tn);sum+=abs(present-track[j].tn);present=track[j].tn;}
	} 
	else
	{    
	if(option==1)  //自低向高走
		{
		 for(j=start;j<=n;j++) {printf("%d ",track[j].tn);sum+=abs(present-track[j].tn);present=track[j].tn;}
		 for(j=start-1;j>=1;j--) {printf("%d ",track[j].tn);sum+=abs(present-track[j].tn);present=track[j].tn;}
		} 
	else if(option==2)  //自高向低走 
		{
			for(j=start;j>=1;j--){printf("%d ",track[j].tn);sum+=abs(present-track[j].tn);present=track[j].tn;}
			for(j=start+1;j<=n;j++){printf("%d ",track[j].tn);sum+=abs(present-track[j].tn);present=track[j].tn;}
		} 
	printf("\n\n磁道移动总数sum=%d\n",sum);
	printf("平均寻道总数=%lf\n",sum/(float)n);
	}
}

int main()
{
	int n;
	int max,min,current;
	int option;    //用于磁头移动方向选择 
	printf("\t\t最短寻道时间优先\n\n");
	printf("请输入请求进程的个数(1-50):");
	scanf("%d",&n);
	printf("请输入最小磁道号:");
	scanf("%d",&min);
	printf("请输入最大磁道号:");
	scanf("%d",&max);
	printf("请输入当前磁头所在的位置:");
	scanf("%d",¤t);
	printf("\n请选择磁头的移动方向: 1.自低向高; 2.自高向低。\n");
	scanf("%d",&option);
	randomnumber(n,max,min);
	//for(int i=1;i<=N;i++) //检验产生的数是否符合要求 
	//printf("%d %d\n",track[i].tn,track[i].flag);
	printf("\n磁道请求调度先后顺序为:\n");
	for(int j=1;j<=n;j++)
	printf("%d\t",track[j].tn);
	SCAN(n,current,max,min,option);
	return 0;	
}



  • 4
    点赞
  • 0
    评论
  • 19
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 书香水墨 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值