操作系统课设考试-磁盘调度算法详细解读(Java实现)

磁盘调度算法

磁盘调度算法视频讲解地址(考试专用)

磁盘调度算法,包括先来先服务(FCFS)、最短寻道优先算法(SSTF)、扫描算法(SCAN)、循环扫描算法等(CSCAN)等等,各种算法的详细介绍在操作系统等书中有详细介绍。
三种算法的简介为:

1、FCFS:按磁盘访问请求的到来顺序进行响应。如若有六个磁盘访问请求依次到来,六个请求所请求访问的磁道号为33,78,55,120,63,70;则根据FCFS,将按请求到来顺序进行调度响应,所以磁盘访问顺序为:33,78,55,120,63,70。

2、SSTF:此算法优先选取欲访问的磁道距离当前磁头所在位置最近的请求进行调度。如若有六个磁盘访问请求依次到来,六个请求所请求访问的磁道号为33,78,55,120,63,70;并假设磁头初始时在磁道号为60的位置,则磁盘访问顺序为:63,70,78,55,33,120.(离哪个近就先访问哪个)。

3、SCAN:此算法在SSTF的基础上规定了磁头的运动方向,按磁头初始运动方向,选取此方向上欲访问磁道距离磁头所在位置最近的请求进行调度。切磁头只能继续向该方向行进,直至该方向所有请求均调度完毕。若一组磁道访问请求如上,磁头初始位置仍为60,并假设此时磁头运动方向为磁道号增大方向,则磁盘访问顺序变为:63,70,78,120,55,33. (若方向减小的话:55,33,63,70,78,120)。

演示截图

操作系统课设考试-磁盘调度算法详细解读(Java实现)_第1张图片
FCFS:按磁盘访问请求的到来顺序进行响应。
操作系统课设考试-磁盘调度算法详细解读(Java实现)_第2张图片
SSTF:此算法优先选取欲访问的磁道距离当前磁头所在位置最近的请求进行调度。
操作系统课设考试-磁盘调度算法详细解读(Java实现)_第3张图片
SCAN:此算法在SSTF的基础上规定了磁头的运动方向,按磁头初始运动方向
操作系统课设考试-磁盘调度算法详细解读(Java实现)_第4张图片

代码实现

Request

package com.sram.beans;

public class Request {
	private int id; //请求号,唯一标识一个请求
	private int number; //欲访问的磁道号
	private int flag; //是否已被调度的标记,初始为0,表示为被调度。
	public Request(){ //空白构造器
		this.id=0;
		this.number=0;
		this.flag=0;
	}
	public Request(int id,int num){ //带参构造器
		this.id=id;
		this.number=num;
		this.flag=0;
	}
	public void setId(int id){
		this.id=id;
	}
	
	// 以下是一系列set和get方法
	public int getId(){
		return this.id;
	}
	
	public void setNumber(int number){
		this.number=number;
	}
	public int getNumber(){
		return this.number;
	}
	
	public void setFlag(int flag){
		this.flag=flag;
	}
	public int getFlag(){
		return this.flag;
	}
}

Work

package com.sram.beans;

import java.util.HashSet;
import java.util.Random;
import java.util.Set;

public class Work {
	private int start; //允许访问的磁道号范围的起始磁道号
	private int end; //允许访问的磁道号范围的终止磁道号
	// 即请求可请求访问的磁道号在start与end之间
	private int num; //所要产生的磁盘访问请求数量
	public Work(){ //不带参构造器
		this.start=0;
		this.end=0;
		this.num=0;
	}
	public Work(int start,int end,int num){ //带参构造器
		this.start=start;
		this.end=end;
		this.num=num;
	}
	public int getStart(){
		return this.start;
	}
	public int getEnd(){
		return this.end;
	}
	
	public Request[] getRandomRequest(){ //产生磁盘访问请求的方法
		Request req[]=new Request[num]; //数组声明num个请求
		Random random=new Random();
		Set<Integer> set=new HashSet<Integer>();
		while(true){ //为num个请求依次生成要访问的磁道号,放入set集合
			set.add((int)(random.nextInt(end-start)+start));
			if(set.size()==num)
				break;
		}
		int i=0;
		//将set集合中的数取出依次付给各请求。使用set的目的是让num个访问请求要访问的磁道号各不同。
		for(int temp:set){
			req[i]=new Request(i+1,temp);
			i++;
		}
		return req;
	}
}

Client

package com.sram.client;
import java.util.Scanner;

import com.sram.beans.Work;
import com.sram.test.DiaoDu;

public class Client {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int start,end,num;
		Scanner in=new Scanner(System.in);
		System.out.println("设定磁道起止道号:");
		
		start=in.nextInt();
		
		end=in.nextInt();
		System.out.print("输入磁盘访问的请求数:");
		num=in.nextInt();
		
		Work work=new Work(start,end,num);
		DiaoDu diaodu=new DiaoDu(work);
		
		System.out.println();
		System.out.println("*************先来先服务调度法*************");
		diaodu.FCFS();
		
		System.out.println();
		System.out.println("***********最短寻道时间优先调度法************");
		diaodu.SSTF();
		
		System.out.println();
		System.out.println("****************扫描调度法*****************");
		diaodu.SCAN();
	}
}

DiaoDu

package com.sram.test;

import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.TreeSet;

import com.sram.beans.Request;
import com.sram.beans.Work;


public class DiaoDu {
	Work work;
	Request[] request;
	int begin;//磁头初始位置
	DecimalFormat df = new DecimalFormat("0.000");
	public DiaoDu(Work work){//构造器,接收一个作业
		this.work=work;
		request=work.getRandomRequest();
		//磁头初始位置设为所允许访问磁道号范围的中间值。
		//如若磁道访问允许范围为100~300,则磁头初始位置在200处。
		begin=(work.getStart()+work.getEnd())/2;
	}
	
	public void FCFS(){//先来先服务算法
		begin=(work.getStart()+work.getEnd())/2;
		Request[] req=request;
		System.out.println("磁道号区间:"+work.getStart()+"到"+work.getEnd());
		System.out.println("磁头初始时所在磁道号:"+begin);
		
		double sum=0;
		System.out.println("请求号        被访问的下一个磁道号               移动距离");
		for(Request r:req){						
			System.out.println("--"+r.getId()+"----------------"+r.getNumber()+"-----------------"+Math.abs(begin-r.getNumber())+"--");
			sum+=Math.abs(begin-r.getNumber());
			begin=r.getNumber();
		}
		System.out.println("***********平均寻道长度为:"+df.format(sum/req.length)+"************");
	}
	
	
	public void SSTF(){//最短寻道优先
		begin=(work.getStart()+work.getEnd())/2;
		Request[] req=request;
		System.out.println("磁道号区间:"+work.getStart()+"到"+work.getEnd());
		System.out.println("磁头初始时所在磁道号:"+begin);
		
		int t=0;
		double sum=0;
		System.out.println("请求号        被访问的下一个磁道号               移动距离");
		for(int i=0;i<req.length;i++){
			int temp=work.getEnd();
			for(int j=0;j<req.length;j++){
				if(Math.abs(req[j].getNumber()-begin)<temp&&req[j].getFlag()==0){
					temp=Math.abs(req[j].getNumber()-begin);					
					t=j;
				}
			}			
			System.out.println("--"+req[t].getId()+"----------------"+req[t].getNumber()+"-----------------"+temp+"--");
			begin=req[t].getNumber();
			req[t].setFlag(1);
			sum+=temp;
		}
		System.out.println("***********平均寻道长度为:"+df.format(sum/req.length)+"***********");
	}
	
	
	
	public void SCAN(){//扫描算法
		begin=(work.getStart()+work.getEnd())/2;
		Request[] req=request;
		int direction;//磁头运动方向方向
		System.out.println("设定磁头初始化运动方向(1:磁道号增大方向    -1:磁道号减小方向):");
		direction=new Scanner(System.in).nextInt();
		System.out.println("磁道号区间:"+work.getStart()+"到"+work.getEnd());
		System.out.println("磁头初始时所在磁道号:"+begin);
		if(direction==1)
			System.out.println("磁头初始运动方向: 磁道号增大方向");
		else
			System.out.println("磁头初始运动方向: 磁道号减小方向");
		
		Map<Integer,Request> map=new HashMap<Integer,Request>();
		TreeSet<Integer> ts1=new TreeSet<Integer>();
		TreeSet<Integer> ts2=new TreeSet<Integer>();
		for(Request r:req){
			if(r.getNumber()>=begin){
				map.put(r.getNumber(), r);
				ts1.add(r.getNumber());
			}
			else{
				map.put(r.getNumber(), r);
				ts2.add(r.getNumber());
			}
		}		
		
		
		System.out.println("请求号        被访问的下一个磁道号               移动距离");
		double sum=0;
		if(direction==1){

			for(int temp:ts1){
				System.out.println("--"+map.get(temp).getId()+"----------------"+temp+"-----------------"+Math.abs(temp-begin));
				sum+=Math.abs(temp-begin);
				begin=temp;
			}
			for(int temp:ts2.descendingSet()){
				System.out.println("--"+map.get(temp).getId()+"----------------"+temp+"-----------------"+Math.abs(temp-begin));
				sum+=Math.abs(temp-begin);
				begin=temp;
			}
			
		}
		
		else{
			for(int temp:ts2.descendingSet()){
				System.out.println("--"+map.get(temp).getId()+"----------------"+temp+"-----------------"+Math.abs(temp-begin));
				sum+=Math.abs(temp-begin);
				begin=temp;
			}
			for(int temp:ts1){
				System.out.println("--"+map.get(temp).getId()+"----------------"+temp+"-----------------"+Math.abs(temp-begin));
				sum+=Math.abs(temp-begin);
				begin=temp;
			}
		}
		System.out.println("***********平均寻道长度为:"+df.format(sum/req.length)+"***********");
	}	
}

喜欢的,点个赞!感谢支持!

你可能感兴趣的:(操作系统)