设计五:磁盘调度管理
设计目的:
加深对请求磁盘调度管理实现原理的理解,掌握磁盘调度算法。
设计内容:
通过编程实现不同磁盘调度算法。
设定开始磁道号寻道范围,依据起始扫描磁道号和最大磁道号数,随机产生要进行寻道的磁道号序列。选择磁盘调度算法,显示该算法的磁道访问顺序,计算出移动的磁道总数和平均寻道总数。
常用的磁盘调度算法简介如下,请在以下算法中任意选择两种实现,并对算法性能进行分析对比。
1. 最短寻道优先算法SSTF:该算法选择这样的进程:其要求访问的磁道与当前磁头所在的磁道距离最近,以使每次的寻道时间最短。
2. 扫描算法SCAN:该算法不仅考虑到欲访问的磁道与当前磁道间的距离,更优先考虑的是磁头当前的移动方向。例如,当磁头正在自里向外移动时,SCAN算法所考虑的下一个访问对象,应是其欲访问的磁道既在当前磁道之外,又是距离最近的。这样自里向外地访问,直至再无更外的磁道需要访问时,才将磁臂换向为自外向里移动。
3.循环扫描算法CSCAN:CSCAN算法规定磁头单向移动,例如,只是自里向外移动,当磁头移到最外的磁道并访问后,磁头立即返回到最里的欲访问的磁道,亦即将最小磁道号紧接着最大磁道号构成循环,进行循环扫描。
import java.util.Arrays;
import java.util.Scanner;
import java.util.Random;
public class RRR {
public static void main(String []arg){
int count;//磁道总数
int now;//当前磁道
int a;
SSTF sstf=new SSTF();
SCAN scan=new SCAN();
Scanner choose=new Scanner(System.in);
System.out.println("请选择算法:1.SSTF 2.SCAN");
a=choose.nextInt();
Scanner in=new Scanner(System.in);
System.out.print("输入要访问的磁道总数:");
count=in.nextInt();
int []cidao=new int [count];//磁道
System.out.print("输入当前磁道号: ");
now=in.nextInt();
System.out.print("用随机数生成磁道: ");
Random rand = new Random();
for(int i = 0; i < count; i++) {
cidao[i] = rand.nextInt(1000); //随机生成1000以内的数
}
for(int i = 0; i < count; i++) {
System.out.print(cidao[i]+" ");
}
System.out.println();
/*System.out.print("输入磁道:");
for(int i=0;i<count;i++)
{
cidao[i]=in.nextInt();
}*/
System.out.print("按升序排列为: ");
Arrays.sort(cidao);//排序
for(int p=0;p<cidao.length;p++)
System.out.print(cidao[p]+" ");
System.out.println();
switch(a) {
case 1: sstf.deal(cidao,now,count);break;
case 2: scan.deal(cidao,now,count);break;
default:System.out.println("非法输入");break;
}
}
/*
void input(){
Scanner in=new Scanner(System.in);
System.out.print("输入要访问的磁道总数:");
count=in.nextInt();
System.out.print("输入当前磁道号: ");
now=in.nextInt();
System.out.print("输入磁道:");
for(int i=0;i<count;i++)
{
cidao[i]=in.nextInt();
}
}*/
}
class SSTF{
int sum=0;//总磁道长度
float ave=0;//平均磁道长度
int m=1;
int l;
int h;
void deal(int []cidao,int now,int count)
{
// Arrays.sort(cidao);//排序
int n,k;
n=now;
if(now>=cidao[count-1])//若当前磁道大于磁道排序中的最大数,则从大到小扫描
{
System.out.print("磁道排序为: ");
for(int i=count-1;i>=0;i--){
System.out.print(cidao[i]+" ");
k=n-cidao[i]; //由于已经排列好,所以只需从大到小依次相减即可得出
sum=sum+k; //磁道长度
n=cidao[i];
}
}
if(now<=cidao[0])//若当前磁道小于磁道排序中的最小数,则从小到大扫描
{
System.out.print("磁道排序为: ");
for(int i=0;i<count;i++){
System.out.print(cidao[i]+" ");
k=cidao[i]-n;
sum=sum+k;
n=cidao[i];
}
}
if(now>cidao[0]&&now<cidao[count-1])//当前磁道处在磁道排序中间某处
{
System.out.print("磁道排序为: ");
while(cidao[m]<now)//寻找当前磁道处在哪俩个磁道之间
{
m++;
}
l=m-1;h=m;
while( l>=0 && h<count)
{
if(n-cidao[l]<=cidao[h]-n)
{
System.out.print(cidao[l]+" ");//该处和上面第一种情况算法相同
k=n-cidao[l];
sum=sum+k;
n=cidao[l];
l--;
}else {
System.out.print(cidao[h]+" ");//该处和上面第二种情况算法相同
k=cidao[h]-n;
sum=sum+k;
n=cidao[h];
h++;
}
}
if(l==-1) //磁头移动到序列的最小号,返回外侧扫描仍未扫描的磁道
{
for(int j=h;j<count;j++) // 当前磁道为排序中的第一个时,算法和第二种情况相同
{
System.out.print(cidao[j]+" ");
k=cidao[j]-n;
sum=sum+k;
n=cidao[j];
}
}
if(h==count) //磁头移动到序列的最大号,返回内侧扫描仍未扫描的磁道
{
for(int j=l;j>=0;j--)
{
System.out.print(cidao[j]+" ");//当前磁道为排序中的最后一个时,算法和第一种情况相同
k=n-cidao[l];
sum=sum+k;
n=cidao[l];
}
}
}
ave=(float)(sum)/(float)(count);
System.out.println();
System.out.println("寻道总和: "+sum);
System.out.println("平均寻道长度: "+ave);
}
}
class SCAN {
int sum=0;//总磁道长度
float ave=0;//平均磁道长度
int m=1;
int l,h;
boolean direction;
Scanner choose=new Scanner(System.in);
//Arrays.sort(cidao);//排序
void deal(int []cidao,int now,int count) {
int n,k;
n=now;
System.out.println("选择移动臂扫描方向:1.向外 0.向内");
int x=choose.nextInt();
if(x==1)
direction=true;
else
direction=false;
if(now>=cidao[count-1])//若当前磁道大于磁道排序中的最大数,则从大到小扫描
{
System.out.print("磁道排序为: "); //和SSTF的第一种情况类似
for(int i=count-1;i>=0;i--) {
System.out.print(cidao[i]+" ");
k=n-cidao[i];
sum=sum+k;
n=cidao[i];
}
}
if(now<=cidao[0])//若当前磁道小于磁道排序中的最小数,则从小到大扫描
{
System.out.print("磁道排序为: ");
for(int i=0;i<count;i++) {
System.out.println(cidao[i]+" "); //和SSTF的第二种情况类似
k=cidao[i]-n;
sum=sum+k;
n=cidao[i];
}
}
if(now>cidao[0]&&now<cidao[count-1])//当前磁道处在磁道排序中间某处
{
System.out.print("磁道排序为: ");
while(cidao[m]<now)//寻找当前磁道处在哪俩个磁道之间
{
m++;
}
l=m-1;h=m;
if(direction==false)//选择移动臂方向向内,先向内扫描
{
for(int j=l;j>=0;j--) {//输出向内扫描的排序
System.out.print(cidao[j]+" ");
k=n-cidao[j];
sum=sum+k;
n=cidao[j];
}
for(int j=h;j<count;j++) {//输出剩下的向外的排序
System.out.print(cidao[j]+" ");
k=cidao[j]-n;
sum=sum+k;
n=cidao[j];
}
}else //选择移动臂向外扫描
{
for(int j=h;j<count;j++) { //输出向外扫描的排序
System.out.print(cidao[j]+" ");
k=cidao[j]-n;
sum=sum+k;
n=cidao[j];
}
for(int j=l;j>=0;j--) { //输出输出剩下的向内的排序
System.out.print(cidao[j]+" ");
k=n-cidao[j];
sum=sum+k;
n=cidao[j];
}
}
}
ave=(float)sum/(float)count;
System.out.println();
System.out.println("寻道总和: "+sum);
System.out.println("平均寻道长度: "+ave);
}
}