1. 程式人生 > >Java 作業系統 磁碟排程修改版

Java 作業系統 磁碟排程修改版

設計五:磁碟排程管理

設計目的:

加深對請求磁碟排程管理實現原理的理解,掌握磁碟排程演算法。

設計內容:

通過程式設計實現不同磁碟排程演算法。

設定開始磁軌號尋道範圍,依據起始掃描磁軌號和最大磁軌號數,隨機產生要進行尋道的磁軌號序列。選擇磁碟排程演算法,顯示該演算法的磁軌訪問順序,計算出移動的磁軌總數和平均尋道總數。

常用的磁碟排程演算法簡介如下,請在以下演算法中任意選擇兩種實現,並對演算法效能進行分析對比。

1. 最短尋道優先演算法SSTF:該演算法選擇這樣的程序:其要求訪問的磁軌與當前磁頭所在的磁軌距離最近,以使每次的尋道時間最短。

2. 掃描演算法SCAN:該演算法不僅考慮到欲訪問的磁軌與當前磁軌間的距離,更優先考慮的是磁頭當前的移動方向。例如,當磁頭正在自裡向外移動時,SCAN演算法所考慮的下一個訪問物件,應是其欲訪問的磁軌既在當前磁軌之外,又是距離最近的。這樣自裡向外地訪問,直至再無更外的磁軌需要訪問時,才將磁臂換向為自外向裡移動。

3.迴圈掃描演算法CSCAN:CSCAN演算法規定磁頭單向移動,例如,只是自裡向外移動,當磁頭移到最外的磁軌並訪問後,磁頭立即返回到最裡的欲訪問的磁軌,亦即將最小磁軌號緊接著最大磁軌號構成迴圈,進行迴圈掃描。

程式碼如下:

import java.util.Scanner;
import java.util.Arrays;
import java.util.Random;


class Cipandiaodu{
	public static void main(String[] args){
		/*
		要用到的幾種演算法分別是
		最短尋道時間優先排程演算法
		迴圈掃描排程演算法
		*/
		Scanner reader=new Scanner(System.in);	
		System.out.println("請輸入演算法:1、最短尋道時間優先排程演算法    2、迴圈掃描排程演算法");
		int input=reader.nextInt();
		switch(input){
		case 1:
			SSTF hhh = new SSTF();
			hhh.way();
			break;
		case 2:
			CSCAN hh = new CSCAN();
			hh.way();
			break;
		default:
		System.out.println("非法輸入");
		break;
	}
}
}


	
	class SSTF{
	void way(){
   int k=1;
   int now,l,r;
   int i,j,sum=0;
   float ave;
   int num;
   Scanner input = new Scanner(System.in);
   System.out.println("請輸入磁軌數:");
   num = input.nextInt();
   int[] cidao=new int[num];
   Random rand = new Random();
   for(i = 0; i < num; i++) {
	   cidao[i] = rand.nextInt(200) + 1 ;
   }
   System.out.print("磁軌序列為:");
   for(i = 0; i < num; i++) {
	   System.out.print(cidao[i]+"  ");
   }
   System.out.println();
   Arrays.sort(cidao);
 	System.out.print("請輸入當前的磁軌號:");
	Scanner w=new Scanner(System.in);
	now = w.nextInt();
   if(cidao[num-1]<=now)   //若當前磁軌號大於請求序列中最大者,則直接由外向內依次給予各請求服務
   {
	  System.out.println("磁碟掃描序列為:");
      for(i=num-1;i>=0;i--)
      System.out.print(cidao[i]+" ");
      sum=now-cidao[0];
   }
   if(cidao[0]>=now)   //若當前磁軌號小於請求序列中最小者,則直接由內向外依次給予各請求服務
   {
	  System.out.println("磁碟掃描序列為:");
      for(i=0;i<num;i++)
	  System.out.print(cidao[i]+" ");
      sum=cidao[num-1]-now;
   }
   if(now>cidao[0]&&now<cidao[num-1])   //若當前磁軌號大於請求序列中最小者且小於最大者
   {
	   System.out.println("磁碟掃描序列為:");
       while(cidao[k]<now)    //確定當前磁軌在已排的序列中的位置
	   {
          k++;
	   }
       l=k-1;
       r=k;
       while((l>=0)&&(r<num))   //當前磁軌在請求序列範圍內
	   {
          if((now-cidao[l])<=(cidao[r]-now))   //選擇與當前磁軌最近的請求給予服務
		  {
			 System.out.print(cidao[l]+" ");
             sum+=now-cidao[l];
             now=cidao[l];
             l=l-1;
		  }
          else
		  {
			 System.out.print(cidao[r]+" ");
             sum+=cidao[r]-now;
             now=cidao[r];
             r=r+1;
		  }
	   }
       if(l==-1)   //磁頭移動到序列的最小號,返回外側掃描仍未掃描的磁軌
	   {
          for(j=r;j<num;j++)
		  {
			 System.out.print(cidao[j]+" ");
		  }
          sum+=cidao[num-1]-cidao[0];
	   }
       else    //磁頭移動到序列的最大號,返回內側掃描仍未掃描的磁軌
	   {
          for(j=l;j>=0;j--)
		  {
			 System.out.print(cidao[j]+" ");
		  }
          sum+=cidao[num-1]-cidao[0];
	   }
   }
   ave=(float)(sum)/(float)(num);
   System.out.println();
   System.out.println("平均尋道長度: "+ave);
}
	}



	class CSCAN{
	void way(){
   int k=1;
   int now,l,r;
   int i,j,sum=0;
   int a;
   float ave;
   int num;
   Scanner input = new Scanner(System.in);
   System.out.println("請輸入磁軌數:");
   num = input.nextInt();
   int[] cidao=new int[num];
   Random rand = new Random();
   for(i = 0; i < num; i++) {
	   cidao[i] = rand.nextInt(200) + 1 ;
   }
   System.out.print("磁軌序列為:");
   for(i = 0; i < num; i++) {
	   System.out.print(cidao[i]+"  ");
   }
   System.out.println();
    Arrays.sort(cidao);
    System.out.print("請輸入當前的磁軌號:");
	Scanner w=new Scanner(System.in);
	now=w.nextInt();
   if(cidao[num-1]<=now)   //若當前磁軌號大於請求序列中最大者,則直接將移動臂移動到最小號磁軌依次向外給予各請求服務 
   {
	  System.out.println("磁碟掃描序列為:");
      for(i=0;i<num;i++)
      System.out.print(cidao[i]+" ");
      sum = now-2*cidao[0]+cidao[num-1];
   }
   if(cidao[0]>=now) //若當前磁軌號小於請求序列中最小者,則直接由內向外依次給予各請求服務,此情況同最短尋道優先
   {
	  System.out.println("磁碟掃描序列為:");
      for(i=0;i<num;i++)
      System.out.print(cidao[i]+" ");
      sum=cidao[num-1]-now;
   }
   if(now>cidao[0]&&now<cidao[num-1])  //若當前磁軌號大於請求序列中最小者且小於最大者
   {
	  System.out.println("磁碟掃描序列為:");
      while(cidao[k]<now)    //單向反覆地從內向外掃描
	  {
          k++;
	  }
      l=k-1;
      r=k;
      for(j=r;j<num;j++)
	  {
		  System.out.print(cidao[j]+" ");
	  }
      for(j=0;j<r;j++)     //當掃描完最大號磁軌,磁頭直接移動到最小號磁軌,再向外掃描未掃描的磁軌
	  {
		  System.out.print(cidao[j]+" ");
	  }
      sum=2*cidao[num-1]+cidao[l]-now-2*cidao[0];
   }
   ave=(float)(sum)/(float)(num);
   System.out.println();
   System.out.println("平均尋道長度: "+ave);
}
	}