操作系统之作业调度实验(多道系统)

这次的实验跟上次类似,只不过多加了多道的概念。

依旧是下面几个算法:

采用先来先服务(FCFS)

最短作业优先(SJF)

响应比高者优先(HRN)

运行结果如下:

代码如下: 

import java.util.LinkedList;
import java.util.Queue;

public class source {
	public static void main(String args[]) {

		Control control = new Control();
		control.FCFS();
		System.out.println("\n\n");
		control.SJF();
		System.out.println("\n\n");
		control.HRRF();
	}
	
}
class Control{
	private JCB job[];
	private int size = 5;
	private int timeSimulator = 0;
	private int systemMachine = 4;//系统资源数
	private int systemRAM = 100;
	private boolean jump[];//资源不满足的应该跳过
	Queue<JCB> waitExec = new LinkedList<JCB>();//定义一个队列储存目前系统可以满足其需求的作业
	class JCB{
		StringBuffer name = new StringBuffer("");//作业名
		int order;//记录作业的初始位置
		int ramRequire;//所需资源数
		int machineRequire;
		boolean beenVisited;//判断该作业是否已经被执行过
		boolean enterQueue;//判断该作业是否已经进入了就绪队列状态
		int enterSystemTime;//进入输入井的时间
		int beginWorkTime;//调入主存的时间(在单道调度中即位进入cpu的时间)
		int runTime;//运行所需时间
		int FinishTime;//完成时间
		int totalTime;//周转时间
		int enterMemoryTime;
		double weightTotalTime;//带权周转时间
		double responceRate = 0;//响应比
	}
	public boolean checkSatisfy(int i) {
		if(job[i].beenVisited == true)
			return false;
		if(job[i].enterSystemTime > timeSimulator)
			return false;
		if(job[i].enterQueue == true)
			return false;
		if(job[i].ramRequire > systemRAM||job[i].machineRequire > systemMachine)
			return false;
		return true;
	}
	//先来先服务算法(多道)
	//1、先检查当前时间段进入输入井的作业哪些作业能够满足要求(遍历)
	//2、将能够满足请求的作业按先来先服务的顺序推入队列中
	//3、执行一个队列中的队首作业后释放作业占有的系统资源再重复第一步骤
	public void FCFS() {
		int numExec = size;
		JCB temp;
		System.out.println("FCFS调度算法");
		initial();
		//检查当前时间段进入输入井的作业哪些作业能够满足要求
		while(numExec > 0) {
			for(int i = 0;i < size;i++) {
				if(checkSatisfy(i) == true) {
					if(job[i].enterQueue == false) {
						job[i].enterQueue = true;
						System.out.println(job[i].name + "要求的资源能够满足,进入主存");
						waitExec.add(job[i]);
						job[i].enterMemoryTime = timeSimulator;
						systemRAM -= job[i].ramRequire;
						systemMachine -= job[i].machineRequire;
					}
				}
			}
			if(waitExec.peek() != null) {
				temp = waitExec.poll();
				System.out.println(temp.name + "开始执行...");
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				temp.beenVisited = true;
				//释放资源
				systemRAM += temp.ramRequire;
				systemMachine += temp.machineRequire;
				//设置作业开始执行和结束运行的时间
				temp.beginWorkTime = timeSimulator;
				temp.FinishTime = temp.beginWorkTime + temp.runTime;
				timeSimulator = temp.FinishTime;
				totalTime(temp.order);
				calcWeightTotalTime(temp.order);
				numExec--;
				System.out.println(temp.name + "执行结束...");
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			//执行一个队列中的队首作业后释放作业占有的系统资源再重复第一步骤
		}
		System.out.println("\t\t FCFS调度算法运行结果");
		try {
			Thread.sleep(200);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		printMess();
	}
	public void totalTime(int i) {
		job[i].totalTime = job[i].FinishTime - job[i].enterSystemTime;
	}
	 public void calcWeightTotalTime(int i) {
		 job[i].weightTotalTime = job[i].totalTime*1.0 / job[i].runTime;
	 }
	 public void createJumpArray() {
		 jump = new boolean[size];
		 for(int i = 0;i < size;i++) {
			 if(checkSatisfy(i) == false) {
				 jump[i] = true;
			 }
		 }
	 }
	//短作业优先算法
	//1、先检查当前时间段进入输入井的作业哪些作业能够满足要求(遍历)
	//2、将能够满足要求的作业按运行时间从短到长推入队列
	//3、执行一个队列中的队首作业后释放作业占有的系统资源再重复第一步骤
	public void SJF() {
		System.out.println("SJF调度算法");
		initial();
		int minJob = -1;
//		minJob = findMinJob();
		int numExec = size;
		JCB temp;
		//检查当前时间段进入输入井的作业哪些作业能够满足要求
		//应当从系统资源可满足的作业中选取最小作业
		while(numExec > 0) {
			for(int i = 0;i < size;i++) {
				createJumpArray();
				minJob = findMinJob();
				if(minJob == -1)
				{
					break;
				}
				if(job[minJob].enterQueue == false) {
					job[minJob].enterQueue = true;
					System.out.println(job[minJob].name + "要求的资源能够满足,进入主存");
					waitExec.add(job[minJob]);
					job[minJob].enterMemoryTime = timeSimulator;
					systemRAM -= job[minJob].ramRequire;
					systemMachine -= job[minJob].machineRequire;
				}
			}
			if(waitExec.peek() != null) {
				temp = waitExec.poll();
				System.out.println(temp.name + "开始执行...");
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				temp.beenVisited = true;
				//释放资源
				systemRAM += temp.ramRequire;
				systemMachine += temp.machineRequire;
				//设置作业开始执行和结束运行的时间
				temp.beginWorkTime = timeSimulator;
				temp.FinishTime = temp.beginWorkTime + temp.runTime;
				timeSimulator = temp.FinishTime;
				totalTime(temp.order);
				calcWeightTotalTime(temp.order);
				numExec--;
				System.out.println(temp.name + "执行结束...");
			}
			//执行一个队列中的队首作业后释放作业占有的系统资源再重复第一步骤
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		System.out.println("\t\t SJF调度算法运行结果");
		try {
			Thread.sleep(200);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		printMess();
	}
	//找出最小的运行时间的作业
	public int findMinJob() {
		int min = 0;
		int i;
		for(i = 1;i < size;i++) {
			if(jump[i] == false&&job[i].runTime < job[min].runTime) {
				min = i;
			}
		}
		return min;
	}
	//响应比最高优先算法
	public void HRRF() {
		System.out.println("HRRF调度算法");
		initial();
		int bestJob = -1;
//		bestJob = findMinJob();
		int numExec = size;
		JCB temp;
		//检查当前时间段进入输入井的作业哪些作业能够满足要求
		//应当从系统资源可满足的作业中选取最小作业
		while(numExec > 0) {
			for(int i = 0;i < size;i++) {
				createJumpArray();
				bestJob = findBestResponceRate();
				if(bestJob == -1) {
					break;
				}
				if(job[bestJob].enterQueue == false) {
					job[bestJob].enterQueue = true;
					System.out.println(job[bestJob].name + "要求的资源能够满足,进入主存");
					waitExec.add(job[bestJob]);
					job[bestJob].enterMemoryTime = timeSimulator;
					systemRAM -= job[bestJob].ramRequire;
					systemMachine -= job[bestJob].machineRequire;
				}
			}
			if(waitExec.peek() != null) {
				temp = waitExec.poll();
				System.out.println(temp.name + "开始执行...");
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				temp.beenVisited = true;
				//释放资源
				systemRAM += temp.ramRequire;
				systemMachine += temp.machineRequire;
				//设置作业开始执行和结束运行的时间
				temp.beginWorkTime = timeSimulator;
				temp.FinishTime = temp.beginWorkTime + temp.runTime;
				timeSimulator = temp.FinishTime;
				totalTime(temp.order);
				calcWeightTotalTime(temp.order);
				numExec--;
				System.out.println(temp.name + "执行结束...");
			}
			//执行一个队列中的队首作业后释放作业占有的系统资源再重复第一步骤
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		System.out.println("\t\t HRRF调度算法运行结果");
		try {
			Thread.sleep(200);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		printMess();
	}
	//计算作业的响应比
	public void calcResponceRate() {
		for(int i = 0;i < size;i++) {
			if(job[i].beenVisited == false && job[i].enterSystemTime <= timeSimulator) {
				job[i].responceRate = (timeSimulator - job[i].enterSystemTime + job[i].runTime) * 1.0 / job[i].runTime; 
			}
		}
	}
	//找出最高响应比的作业
	public int findBestResponceRate() {
		calcResponceRate();
		int best = -1;
		//找出第一个未被执行过的作业
		int i;
		for(i = 0;i < size;i++) {
			if(jump[i] == false) {
				best = i;
				break;
			}
		}
		for(int j = i;j < size;j++) {
			if(jump[j] == false&&job[best].responceRate < job[j].responceRate) {
				best = j;	
			}
		}
		return best;
	}
	//对作业进行初始化
	public void initial() {
		System.out.print("JOB表初始化中");
		for(int i = 0;i < 40;i++) {
			System.out.print(">");
			try {
				Thread.sleep(15);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		System.out.println("\n初始化成功!");
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		timeSimulator = 0;
		job = new JCB[size];
		for(int i = 0;i < size;i++) {
			job[i] = new JCB();
		}
		for(int i = 0;i < size;i++) {
			
			job[i].name.append( "JOB" + (i+1));
			job[i].order = i;
		}
		job[0].enterSystemTime = 0;
		job[0].runTime = 40;
		job[0].ramRequire = 35;
		job[0].machineRequire = 3;
		
		job[1].enterSystemTime = 10;
		job[1].runTime = 30;
		job[1].ramRequire = 70;
		job[1].machineRequire = 1;
		
		job[2].enterSystemTime = 15;
		job[2].runTime = 20;
		job[2].ramRequire = 50;
		job[2].machineRequire = 3;
		
		job[3].enterSystemTime = 35;
		job[3].runTime = 10;
		job[3].ramRequire = 25;
		job[3].machineRequire = 2;
		
		job[4].enterSystemTime = 40;
		job[4].runTime = 5;
		job[4].ramRequire = 20;
		job[4].machineRequire = 2;
	}
	//打印作业平均周转时间
	public double avgTotalTime() {
		double sum = 0;
		for(int i = 0;i < size;i++) {
			sum += job[i].totalTime;
		}
		return sum*1.0 / size;
	}
	//打印作业总周转时间
	public double calcTotalTime() {
		double sum = 0;
		for(int i = 0;i < size;i++) {
			sum += job[i].totalTime;
		}
		return sum;
	}
	//打印作业带权平均周转时间
	public double avgWeightTotalTime() {
		double sum = 0;
		for(int i = 0;i < size;i++) {
			sum += job[i].weightTotalTime;
		}
		return sum*1.0 / size;
	}
	public double calcWeightTotalTime() {
		double sum = 0;
		for(int i = 0;i < size;i++) {
			sum += job[i].weightTotalTime;
		}
		return sum;
	}
	//对作业表和调度表进行打印输出
	public void printMess() {
		System.out.println("作业名\t进入时间\t运行时间\t作业调度\t进程调度\t结束时间\t周转时间\t带权周转时间\t");
		for(int i = 0;i < size;i++) {
			System.out.println(" " + job[i].name + "\t" + " " + job[i].enterSystemTime  + "\t" + " " + job[i].runTime  + "\t"
			+ " " + job[i].enterMemoryTime + "\t" + " " + job[i].beginWorkTime + "\t" + " " + job[i].FinishTime + "\t" + " " + job[i].totalTime + "\t" + " " +  String.format("%.2f",job[i].weightTotalTime ) + "\t" );
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		System.out.println("\t\t\t\t\t\t" + " " +calcTotalTime() + "\t" + " " + String.format("%.2f",calcWeightTotalTime() ) + "\t");
		System.out.println("平均周转时间"+"\t\t"+avgTotalTime()+"\n"+"作业平均带权周转时间"+"\t" + String.format("%.2f",avgWeightTotalTime()));
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

一、实验目的 本实验要求学生模拟作业调度的实现,用高级语言编写和调试一个或多个作业调度的模拟程序,了解作业调度操作系统中的作用,以加深对作业调度算法的理解。 二、实验内容和要求 1、编写并调度一个多道程序系统作业调度模拟程序。   作业调度算法:采用基于先来先服务的调度算法。可以参考课本中的方法进行设计。 对于多道程序系统,要假定系统中具有的各种资源及数量、调度作业时必须考虑到每个作业的资源要求。 三、实验主要仪器设备和材料 硬件环境:IBM-PC或兼容机 软件环境:C语言编程环境 四、实验原理及设计方案 采用多道程序设计方法的操作系统,在系统中要经常保留多个运行的作业,以提高系统效率。作业调度系统已接纳的暂存在输入井中的一批作业中挑选出若干个可运行的作业,并为这些被选中的作业分配所需的系统资源。对被选中运行的作业必须按照它们各自的作业说明书规定的步骤进行控制。 采用先来先服务算法算法模拟设计作业调度程序。 (1)、作业调度程序负责从输入井选择若干个作业进入主存,为它们分配必要的资源,当它们能够被进程调度选中时,就可占用处理器运行。作业调度选择一个作业的必要条件是系统中现有的尚未分配的资源可满足该作业的资源要求。但有时系统中现有的尚未分配的资源既可满足某个作业的要求也可满足其它一些作业的要求,那么,作业调度必须按一定的算法在这些作业中作出选择。先来先服务算法是按照作业进入输入井的先后次序来挑选作业,先进入输入井的作业优先被挑选,当系统中现有的尚未分配的资源不能满足先进入输入井的作业时,那么顺序挑选后面的作业。 (2) 假定某系统可供用户使用的主存空间共100k,并有5台磁带机。 3)流程图:
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值