基于JAVA的模拟磁盘调度算法SCAN
- 简单讲一下原理
- 功能描述
- 功能描述:
- 算法流程图:
- 话不多说,上代码:
- 利用Disk类来模拟磁盘的工作流程 ,get_cidao()磁道方法为获取磁头的当前位置,set_citou(int f,int c)通过传递俩个整形参数来设置磁头的方向和当前位置
- 利用User类来模拟进程生成需要访问的磁道。set_cidao()方法用来随机生成需要访问的磁道。save_cidao(User user,Disk citou,List seq0,List seq1)方法通过判断磁头的当前位置和方向来判断磁道应存入哪个队列,并将磁道数存入队列中。通过进程的优先级顺序(在磁头移动方向上,离磁头近的进程优先级高)给进程排序.
- 利用Test类来模拟磁头的移动和读取磁道。add_mission(User user,Disk citou ,List seq0,List seq1)方法随机产生小于10个进程。
- 运行结果
思考问题:
1.由于在访问磁盘时间中主要是寻道时间,因此,磁盘调度的目标是使磁盘的平均寻道时间最少。
2. 对于SCAN算法(先按照一个方向(比如从外向内扫描),扫描的过程中依次访问要求服务的序列),当扫描到最里层的一个服务序列时反向扫描,这里要注意,假设最里层为0号磁道,最里面的一个要求服务的序列是5号,访问完5号之后,就反向了,不需要再往里扫。结合电梯过程更好理解,在电梯往下接人的时候,明知道最下面一层是没有人的,它是不会再往下走的。
简单讲一下原理
模拟电梯调度算法,对磁盘调度。磁盘是要供多个进程共享的存储设备,但一个磁盘每个时刻只能为一个进程服务。当有进程在访问某个磁盘时,其他想访问该磁盘的进程必须等待,直到磁盘一次工作结束。当有多个进程提出输入输出请求处于等待状态,可用电梯调度算法从若干个等待访问者中选择一个进程,让它访问磁盘。当存取臂仅需移到一个方向最远的所请求的柱面后,如果没有访问请求了,存取臂就改变方向。
功能描述
系统执行过程:
第一步先获得需要访问的磁道数(有随机数产生),通过判断磁头的当前状态(方向和所在磁道数)将需要访问的磁道数上行和下行队列。
第二步磁头按照当前方向移动,依次按顺序访问当前方向所对应的队列并在队列中将放问后的磁道数删除。
第三步若当前队列已无需要访问的磁道数,则改变磁头方向;若俩个方向的队列都无需要访问的磁道数,则等待。
功能描述:
第一步先获得需要访问的磁道数(有随机数产生),通过判断磁头的当前状态(方向和所在磁道数)将需要访问的磁道数上行和下行队列。
第二步磁头按照当前方向移动,依次按顺序访问当前方向所对应的队列并在队列中将放问后的磁道数删除。
第三步若当前队列已无需要访问的磁道数,则改变磁头方向;若俩个方向的队列都无需要访问的磁道数,则等待。
算法流程图:
话不多说,上代码:
public class Disk {
public int cidao;
public int fangxiang=0;//初始默认为方向向下
public int now_cidao;
public int get_cidao() {
this.cidao=Integer.parseInt(User.num);
return cidao;
}
public void set_citou(int f,int c) {
this.fangxiang=f;
this.now_cidao=c;
}
public Disk get_citou(Disk citou) {
return citou;
}
}
利用Disk类来模拟磁盘的工作流程 ,get_cidao()磁道方法为获取磁头的当前位置,set_citou(int f,int c)通过传递俩个整形参数来设置磁头的方向和当前位置
public class User{
public static String num;
public void set_cidao() {
Integer x=(int)(Math.random()*100)%80;
num=x.toString();
}
public void get_number() {
this.num=num;
}
public void save_cidao(User user,Disk citou,List seq0,List seq1) {
user.set_cidao();
if(Integer.parseInt(user.num)-citou.now_cidao < 0 && citou.fangxiang0) {//存放在下行队列
seq0.add(user.num);
seq0.stream().distinct();
Collections.sort(seq0);
System.out.println(user.num+“成功存放下行队列”);
}
else if(Integer.parseInt(user.num)-citou.now_cidao > 0 && citou.fangxiang0) {//存放在上行队列
seq1.add(user.num);
seq1.stream().distinct();
Collections.sort(seq1);
Collections.reverse(seq1);
System.out.println(user.num+“成功存放上行队列”);
}
else if(Integer.parseInt(user.num)-citou.now_cidao > 0 && citou.fangxiang1) {//存放在上行队列
seq1.add(user.num);
seq1.stream().distinct();
Collections.sort(seq1);
Collections.reverse(seq1);
System.out.println(user.num+“成功存放上行队列”);
}
else if(Integer.parseInt(user.num)-citou.now_cidao < 0 && citou.fangxiang1) {//存放在下行队列
seq0.add(user.num);
seq0.stream().distinct();
Collections.sort(seq0);
System.out.println(user.num+“成功存放下行队列”);
}
}
}
利用User类来模拟进程生成需要访问的磁道。set_cidao()方法用来随机生成需要访问的磁道。save_cidao(User user,Disk citou,List seq0,List seq1)方法通过判断磁头的当前位置和方向来判断磁道应存入哪个队列,并将磁道数存入队列中。通过进程的优先级顺序(在磁头移动方向上,离磁头近的进程优先级高)给进程排序.
public class Test {
private static void add_mission(User user,Disk citou ,List seq0,List seq1) {
for(int i=0;i<Math.random()*100%10;i++) {
user.save_cidao(user, citou, seq0, seq1);
}
}
利用Test类来模拟磁头的移动和读取磁道。add_mission(User user,Disk citou ,List seq0,List seq1)方法随机产生小于10个进程。
运行结果
结果分析
该算法在磁盘调度中克服了最短寻道优先的缺点,既考虑了距离,同时又考虑了方向。但是SCAN算法对最近扫描过的区域不公平(对于磁头扫描过出现的进程,只有等到方向改变的时候才会访问,会增加等待时间),因此,它在访问局部性方面不如FCFS算法和SSTF算法好。