设计五:磁盘调度管理
设计目的:
加深对请求磁盘调度管理实现原理的理解,掌握磁盘调度算法。
设计内容:
通过编程实现不同磁盘调度算法。
设定开始磁道号寻道范围,依据起始扫描磁道号和最大磁道号数,随机产生要进行寻道的磁道号序列。选择磁盘调度算法,显示该算法的磁道访问顺序,计算出移动的磁道总数和平均寻道总数。
常用的磁盘调度算法简介如下,请在以下算法中任意选择两种实现,并对算法性能进行分析对比。
1. 最短寻道优先算法SSTF:该算法选择这样的进程:其要求访问的磁道与当前磁头所在的磁道距离最近,以使每次的寻道时间最短。
2. 扫描算法SCAN:该算法不仅考虑到欲访问的磁道与当前磁道间的距离,更优先考虑的是磁头当前的移动方向。例如,当磁头正在自里向外移动时,SCAN算法所考虑的下一个访问对象,应是其欲访问的磁道既在当前磁道之外,又是距离最近的。这样自里向外地访问,直至再无更外的磁道需要访问时,才将磁臂换向为自外向里移动。
3.循环扫描算法CSCAN:CSCAN算法规定磁头单向移动,例如,只是自里向外移动,当磁头移到最外的磁道并访问后,磁头立即返回到最里的欲访问的磁道,亦即将最小磁道号紧接着最大磁道号构成循环,进行循环扫描。
import java.util.Random;
import java.util.Arrays;
public class Hello {
public static void main(String[] args){
RANDOM Random=new RANDOM();
Random.show();
System.out.println("/");
System.out.println("// 先进先出 //");
System.out.println("/");
FIFO fifo=new FIFO();
fifo.Way(Random);
System.out.println("/");
System.out.println("// 最短寻道时间算法 //");
System.out.println("/");
SSTF sstf=new SSTF();
sstf.Way(Random);
System.out.println("/");
System.out.println("// 扫描算法 //");
System.out.println("/");
CSAN csan=new CSAN();
csan.Way(Random);
System.out.println("/");
System.out.println("// 循环扫描算法 //");
System.out.println("/");
CSCAN cscan=new CSCAN();
cscan.Way(Random);
}
}
class RANDOM{
int num=5; //磁道数
int head=50; //假设磁头一开始指向50
int i;
int a[]=new int[num]; //记录寻到序列
int b[]=new int[num]; //记录磁道访问顺序
void show(){
Random rand = new Random(); //从1-100随机产生要进行寻道的磁道号序列,并放在数组a里
System.out.println("磁道序号为:");
for(i=0; i<num; i++) {
a[i]=rand.nextInt(100) + 1;
System.out.print(a[i]+" ");
}
System.out.print("\n");
}
}
class FIFO{
int head; //假设磁头一开始指向50
int a[]; //记录寻到序列
int b[]; //记录磁道访问顺序
int i,j;
int sum=0; //记录移动的磁道总数
double avg; //记录平均寻道总数
void Way(RANDOM Random){
head=Random.head;
a=new int[Random.num];
b=new int[Random.num];
for(i=0;i<Random.num;i++){
a[i]=Random.a[i];
}
int one=0; //记录一次移动的磁道数
for(i=0;i<Random.num;i++) { //计算移动的磁道总数
one=Math.abs(head-a[i]);
sum=sum+one;
b[i]=a[i];
head=a[i];
}
System.out.println("磁道访问顺序为:");
for(i=0;i<Random.num;i++)
System.out.print(b[i]+" ");
System.out.print("\n");
System.out.println("磁道总数为:"+sum);
avg=sum/(double)Random.num;
System.out.println("平均寻道总数为:"+avg);
}
}
class SSTF{
int head; //假设磁头一开始指向50
int a[]; //记录寻到序列
int b[]; //记录磁道访问顺序
int i,j;
int sum=0; //记录移动的磁道总数
double avg; //记录平均寻道总数
void Way(RANDOM Random){
head=Random.head;
a=new int[Random.num];
b=new int[Random.num];
for(i=0;i<Random.num;i++){
a[i]=Random.a[i];
}
int min=100; //记录最短寻到时间
int mini=0;
for(j=0;j<Random.num;j++){ //寻找最短的寻道磁道
for(i=0;i<Random.num;i++){
if(a[i]!=0){ //0表示已经访问
if(Math.abs(head-a[i])<min) {
min=Math.abs(head-a[i]);
mini=i;
b[j]=a[i]; //记录磁道访问顺序
}
}
}
sum=sum+min; //计算移动的磁道总数
head=a[mini];
a[mini]=0;
min=100;
}
System.out.println("磁道访问顺序为:");
for(i=0;i<Random.num;i++)
System.out.print(b[i]+" ");
System.out.print("\n");
System.out.println("磁道总数为:"+sum);
avg=sum/(double)Random.num;
System.out.println("平均寻道总数为:"+avg);
}
}
class CSAN{
int head; //假设磁头一开始指向50
int a[]; //记录寻到序列
int b[]; //记录磁道访问顺序
int i,j,k;
int sum=0; //记录移动的磁道总数
double avg; //记录平均寻道总数
void Way(RANDOM Random){
head=Random.head;
a=new int[Random.num];
b=new int[Random.num];
for(i=0;i<Random.num;i++){
a[i]=Random.a[i];
}
System.out.println("排序后的磁道序号为:");
Arrays.sort(a);
for(i=0; i<Random.num; i++)
System.out.print(a[i]+" "); //输出排序后的磁道序号
System.out.print("\n");
for(i=0;a[i]<=head;i++) {}
int one=0; //记录一次移动的磁道数
if(Math.abs(head-a[i-1])<=Math.abs(head-a[i])){ //如果左边离磁头更近,磁头就先往左边去,否则往右边去
for(j=i-1,k=0;j>=0;j--,k++) { //先去左边
one=head-a[j];
sum=sum+one;
b[k]=a[j];
head=a[j];
}
for(j=i,k=k;j<Random.num;j++,k++) { //再去右边
one=a[j]-head;
sum=sum+one;
b[k]=a[j];
head=a[j];
}
}
else {
for(j=i,k=0;j<Random.num;j++,k++) { //先去左=右边
one=a[j]-head;
sum=sum+one;
b[k]=a[j];
head=a[j];
}
for(j=i-1,k=k;j>=0;j--,k++) { //再去左边
one=head-a[j];
sum=sum+one;
b[k]=a[j];
head=a[j];
}
}
System.out.println("磁道访问顺序为:");
for(i=0;i<Random.num;i++)
System.out.print(b[i]+" ");
System.out.print("\n");
System.out.println("磁道总数为:"+sum);
avg=sum/(double)Random.num;
System.out.println("平均寻道总数为:"+avg);
}
}
class CSCAN{
int head; //假设磁头一开始指向50
int a[]; //记录寻到序列
int b[]; //记录磁道访问顺序
int i,j;
int sum=0; //记录移动的磁道总数
double avg; //记录平均寻道总数
void Way(RANDOM Random){
head=Random.head;
a=new int[Random.num];
b=new int[Random.num];
for(i=0;i<Random.num;i++){
a[i]=Random.a[i];
}
System.out.println("排序后的磁道序号为:");
Arrays.sort(a);
for(i=0; i<Random.num; i++)
System.out.print(a[i]+" "); //输出排序后的磁道序号
System.out.print("\n");
int one=0; //记录一次移动的磁道数
j=0;
for(i=0;i<Random.num;i++){
if(a[i]>=head) { //先计算大于磁头的
if(a[i]!=0){ //0表示已经访问
b[j]=a[i]; //记录磁道访问顺序
one=a[i]-head; //计算一次移动的磁道数
sum=sum+one; //计算移动的磁道总数
head=a[i];
a[i]=0;
j++;
}
}
}
int k=1;
for(i=0;i<Random.num;i++){ //再计算小于磁头的
if(a[i]>=1 && a[i]<50){
if(a[i]!=0 && k==1){ //第一次当磁头返回到最里的欲访问的磁道
b[j]=a[i];
one=100-head+a[i];
sum=sum+one; //计算移动的磁道总数
head=a[i];
a[i]=0;
j++;
k=0;
}
else{
b[j]=a[i];
one=a[i]-head;
sum=sum+one; //计算移动的磁道总数
head=a[i];
a[i]=0;
j++;
}
}
}
System.out.println("磁道访问顺序为:");
for(i=0;i<Random.num;i++)
System.out.print(b[i]+" ");
System.out.print("\n");
System.out.println("磁道总数为:"+sum);
avg=sum/(double)Random.num;
System.out.println("平均寻道总数为:"+avg);
}
}