进程调度模拟实验
这个操作系统实验课的实验,写出来给大家分享一下,也希望大神能给点指点
设定一组作业或者进程,给定相关参数,对这组作业或者进程,对这组作业或进程按调度算法实施调度,输出调度次序,并计算平均周转时间和带权平均周转时间。使用的调度算法有:
1.先到先服务算法
2.优先级调度算法
3.短作业优先调度算法
4.响应比优先调度算法
进程模拟调度只需要分为以下两步:
1.给出进程的数据结构
2.写出以上已给出的算法
1.以下给出进程的数据结构
其中get set方法就省略了
public class ForkClass {
private int num; //
private String name;
private int priority;//优先级
private double workTime;
private double arriveTime;
private double startTime;//开始运行时间
private double overTime;//运行结束时间
private double TAT;//周转时间
private double WTAT;//带权周转时间
}
2.写算法
(1)先到先服务算法(FIFO)
根据先到先服务的原则,将到达时间小的进程优先放入工作队列,并计算出该进程的结束时间。
//先到先服务算法
public static ArrayList<ForkClass> FCFS(ArrayList<ForkClass> forkArr)
{
ForkClass nowFork;
ArrayList<ForkClass> workArr=new ArrayList<ForkClass>();
nowFork=forkArr.get(0);
//第一个进入工作队列中
forkArr.remove(nowFork);
workArr.add(nowFork);
workArr.get(0).setStartTime(nowFork.getArriveTime());
workArr.get(0).setOverTime(nowFork.getArriveTime()+nowFork.getWorkTime());
//根据先到先服务原则将输入队列排序并放入工作队列中
for(int i=0;i<forkArr.size();i++)
{
for(int j=i+1;j<forkArr.size();j++)
{
if(forkArr.get(i).getArriveTime()>forkArr.get(j).getArriveTime())
{
Collections.swap(forkArr, i, j);
}
}
}
for(ForkClass fc : forkArr)
{
fc.setStartTime(workArr.get(workArr.size()-1).getOverTime());
fc.setOverTime(fc.getStartTime()+fc.getWorkTime());
workArr.add(fc);
}
return workArr;
}
(2)响应比优先调度算法(HRRF)
在写这个算法时,应该先理解响应比是什么
响应比=(等待时间+工作时间)/工作时间
这里还有一个问题就是,计算出工作队列里正在运行存放进程的结束时间,然后将forkArr中小于结束时间的进程都放入等待队列temp中,找出响应比小的进程再将其放入工作队列workArr,并删除forkArr中的进程。
这里的小插曲是当时脑子可能写懵了,所以在寻找最小响应比上,我选择将temp采用从小到大排序然后取第一个的放法2333
public static ArrayList<ForkClass> HRRF(ArrayList<ForkClass> forkArr)
{
ForkClass nowFork;
ArrayList<ForkClass> workArr=new ArrayList<ForkClass>();
nowFork=forkArr.get(0);
//第一个进入工作队列中
forkArr.remove(nowFork);
workArr.add(nowFork);
workArr.get(0).setStartTime(nowFork.getArriveTime());
workArr.get(0).setOverTime(nowFork.getArriveTime()+nowFork.getWorkTime());
//判断响应比,响应比小的先运行
while(!forkArr.isEmpty())
{
ArrayList<ForkClass> temp=new ArrayList<ForkClass>();
for(ForkClass fc : forkArr)
{
if(fc.getArriveTime()<workArr.get(workArr.size()-1).getOverTime())
{
temp.add(fc);
}
}
//找到最小的
double largeHrn=-1;
int flag=-1;
for(ForkClass fc : temp)
{
double hrn=(fc.getWorkTime()+(workArr.get(workArr.size()-1).getOverTime()-fc.getArriveTime()))/fc.getWorkTime();
if(largeHrn<hrn)
{
largeHrn=hrn;
flag=temp.indexOf(fc);
}
}
temp.get(flag).setStartTime(workArr.get(workArr.size()-1).getOverTime());
temp.get(flag).setOverTime(temp.get(flag).getStartTime()+temp.get(flag).getWorkTime());
forkArr.remove(temp.get(flag));
workArr.add(temp.get(flag));
}
return workArr;
}
(3)优先级调度算法(PSA)
顾名思义,优先级调度算法就是以高优先级优先进入队列的方法,其余解释和响应比优先级算法类似,请参照上面的释文。废话不多,上代码
//优先级调度算法
public static ArrayList<ForkClass> PSA(ArrayList<ForkClass> forkArr)
{
ForkClass nowFork;
ArrayList<ForkClass> workArr=new ArrayList<ForkClass>();
nowFork=forkArr.get(0);
//第一个进入工作队列中
forkArr.remove(nowFork);
workArr.add(nowFork);
workArr.get(0).setStartTime(nowFork.getArriveTime());
workArr.get(0).setOverTime(nowFork.getArriveTime()+nowFork.getWorkTime());
//剩下的通过优先级调度算法分别进入工作队列
while(!forkArr.isEmpty())
{
ArrayList<ForkClass> temp=new ArrayList<ForkClass>();
double lastOverTime=workArr.get(workArr.size()-1).getOverTime();
for(ForkClass fc : forkArr)
{
if(fc.getArriveTime()<lastOverTime)
{
temp.add(fc);
}
}
for(int i=0;i<temp.size();i++)
{
for(int j=i+1;j<temp.size();j++)
{
if(temp.get(i).getPriority()<temp.get(j).getPriority())
Collections.swap(temp, i, j);
}
}
temp.get(0).setStartTime(lastOverTime);
temp.get(0).setOverTime(temp.get(0).getStartTime()+temp.get(0).getWorkTime());
workArr.add(temp.get(0));
forkArr.remove(temp.get(0));
}
return workArr;
}
(4)短作业优先算法(SJF)
工作时间的短的优先运行的调度算法,这个也可以直接上代码了吧
//短作业优先算法
public static ArrayList<ForkClass> SJF(ArrayList<ForkClass> forkArr)
{
ForkClass nowFork;
ArrayList<ForkClass> workArr=new ArrayList<ForkClass>();
nowFork=forkArr.get(0);
//第一个进入工作队列中
forkArr.remove(nowFork);
workArr.add(nowFork);
workArr.get(0).setStartTime(nowFork.getArriveTime());
workArr.get(0).setOverTime(nowFork.getArriveTime()+nowFork.getWorkTime());
//剩下的通过短作业优先调度算法分别进入工作队列
while(!forkArr.isEmpty())
{
ArrayList<ForkClass> temp=new ArrayList<ForkClass>();
double lastOverTime=workArr.get(workArr.size()-1).getOverTime();
for(ForkClass fc : forkArr)
{
if(fc.getArriveTime()<lastOverTime)
{
temp.add(fc);
}
}
for(int i=0;i<temp.size();i++)
{
for(int j=i+1;j<temp.size();j++)
{
if(temp.get(i).getWorkTime()>temp.get(j).getWorkTime())
Collections.swap(temp, i, j);
}
}
temp.get(0).setStartTime(lastOverTime);
temp.get(0).setOverTime(temp.get(0).getStartTime()+temp.get(0).getWorkTime());
workArr.add(temp.get(0));
forkArr.remove(temp.get(0));
}
return workArr;
}
到此为止,这个进程调度模拟已经完成了90%了,接下是对一些功能的完善
我写了一个输出的算法,计算了工作队列中的周转时间和平均周转时间,并完成了输出的工作
//输出算法
public static void printArr(ArrayList<ForkClass> forkArr)
{
//计算开始运行时间,结束运行时间 周转时间 带权周转时间
for(ForkClass fc : forkArr)
{
fc.setTAT(fc.getOverTime()-fc.getArriveTime());
fc.setWTAT(fc.getTAT()/fc.getWorkTime());
}
System.out.println("=============================");
System.out.println("序号 进程名 达到时间 运行时间 优先级 开始运行时间 运行结束时间 周转时间 带权周转时间");
for(ForkClass fc : forkArr)
{
System.out.print(fc.getNum());
System.out.print("\t"+fc.getName());
System.out.print("\t"+fc.getArriveTime());
System.out.print("\t"+fc.getWorkTime());
System.out.print("\t"+fc.getPriority());
System.out.print("\t"+fc.getStartTime());
System.out.print("\t\t"+fc.getOverTime());
System.out.print("\t"+fc.getTAT());
System.out.println("\t"+fc.getWTAT());
}
}
}
我还将菜单栏目写在了主函数中
public static void main(String[] args) {
System.out.println("=======进程参数输入=======");
System.out.println("选择调度算法");
System.out.println("1.调用先来先服务调度程序");
System.out.println("2.调用优先级调度程序");
System.out.println("3.调用短作业(进程)调度程序");
System.out.println("4.调用响应比高者优先调度程序");
System.out.println("0.退出");
System.out.println("=========================");
Scanner sc=new Scanner(System.in);
while(true) {
ArrayList<ForkClass> forkArr=new ArrayList<ForkClass>();
forkArr.add(new ForkClass(1,"A",7,2,1));
forkArr.add(new ForkClass(2,"B",8,1,3));
forkArr.add(new ForkClass(3,"C",8.5,2,4));
forkArr.add(new ForkClass(4,"D",9,0.5,2));
switch (sc.nextInt()) {
case 1:
System.out.println("先来先服务算法");
ArrayList<ForkClass> FSFCArr=FCFS(forkArr);
printArr(FSFCArr);
break;
case 2:
System.out.println("优先级优先算法");
ArrayList<ForkClass> PSAArr=PSA(forkArr);
printArr(PSAArr);
break;
case 3:
System.out.println("短作业优先算法");
ArrayList<ForkClass> SJFArr=SJF(forkArr);
printArr(SJFArr);
break;
case 4:
System.out.println("响应比高优先算法");
ArrayList<ForkClass> HRRFArr=HRRF(forkArr);
printArr(HRRFArr);
break;
case 0:
System.exit(0);
break;
}
}
}
到这里,这个进程的模拟调度就全部写完了。
测试一下
完毕!第一次写博客,希望大家多多给我意见。