Java 作業系統 磁碟排程修改版
阿新 • • 發佈:2018-12-26
設計五:磁碟排程管理
設計目的:
加深對請求磁碟排程管理實現原理的理解,掌握磁碟排程演算法。
設計內容:
通過程式設計實現不同磁碟排程演算法。
設定開始磁軌號尋道範圍,依據起始掃描磁軌號和最大磁軌號數,隨機產生要進行尋道的磁軌號序列。選擇磁碟排程演算法,顯示該演算法的磁軌訪問順序,計算出移動的磁軌總數和平均尋道總數。
常用的磁碟排程演算法簡介如下,請在以下演算法中任意選擇兩種實現,並對演算法效能進行分析對比。
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); } }