目录

文章目录

前言

一、实验原理

二、实验步骤

1.创建PCB类

2.创建创建类

3.设计主窗口类

4.调度界面函数

5.算法类及其调度算法通用函数

6.进程调度算法函数

总结



前言

操作系统实验1:进程调度算法,步骤3、4在一个类中,步骤5、6在一个类中。


一、实验原理

(1)先到先服务调度算法:按照进程提交给系统的先后次序来进行调度。

(2)短作业优先调度算法:按照进程所要求的运行时间来衡量。

(3)时间片轮转调度算法:根据先来先服务排序,以一个时间片为单位,依次执行不同的进  程。

(4)优先权调度算法:按照进程的优先权来衡量。

实验要求:

Java进程调度优先级算法 进程调度实验代码java_System

二、实验步骤

1.创建PCB类

代码如下:

package os.test1;

public class PCB {
    String name;    //进程名/进程标识符
    int runtime;   //进程运行时间
    int newruntime;    //进程剩余运行时间(时间片轮转要用)
    int arrivaltime;   //进程到达时间
    int newarrival;    //进程再次到就绪队列队首位置时间
    int priority;    //进程优先级
    int starttime;   //进程开始运行时间
    int endtime;     //进程运行结束时间
    int turntime;    //进程周转时间
    double dturntime;        //带权周转时间
    public PCB(String name,int priority,int runtime,int arrivaltime){
        this.name=name;
        this.priority=priority;
        this.runtime=runtime;
        this.arrivaltime=arrivaltime;
        this.starttime=0;
        this.endtime=0;
        this.turntime=0;
        this.dturntime=0;
        this.newarrival=arrivaltime;    //再次到达就绪队首位置默认为首次到达时间
        this.newruntime=runtime;     //刚开始剩余运行时间为运行时间
    }
}

2.创建创建类

主要负责PCB的创建和检测已经创建好的进程PCB。

代码如下:

package os.test1;

import java.util.ArrayList;

public class Create {
    public ArrayList<PCB> createPcb(ArrayList<PCB> pcbs, String name, int priority, int runtime, int arrivaltime){
        //新进程进数组
        PCB pcb=new PCB(name,priority,runtime,arrivaltime);
        pcbs.add(pcb);
        return pcbs;
    }
    public void check(ArrayList<PCB> pcbs){
        if(pcbs.isEmpty()){
            System.out.println("当前没有进程信息。");
            return;
        }
        for(PCB cur:pcbs){
            System.out.println("进程名:"+cur.name+",优先级:"+cur.priority+",需要运行时间:"+cur.runtime
            +",到达时间:"+cur.arrivaltime);
        }
    }

3.设计主窗口类

实现三个主功能添加进程、进程调度、查看进程。

代码如下:

public class Psch {
    public static void main(String args[]){
        ArrayList<PCB> pcbs=new ArrayList<PCB>();
        Psch.mainMenu(pcbs);
    }
    public static void mainMenu(ArrayList<PCB> pcbs){
        Create create=new Create();
        //测试用例
        PCB pcb=new PCB("a",2,7,3);
        PCB pcb2=new PCB("b",2,5,0);
        PCB pcb3=new PCB("f",5,3,7);
        PCB pcb4=new PCB("z",5,2,4);
        PCB pcb5=new PCB("u",7,2,9);
        pcbs.add(pcb);
        pcbs.add(pcb2);
        pcbs.add(pcb3);
        pcbs.add(pcb4);
        Scanner sc=new Scanner(System.in);
        int count1=1;
        while(count1==1){
            System.out.println("**************************");
            System.out.println("请输入你需要的服务:");
            System.out.println("1.添加新进程");
            System.out.println("2.选择调度算法");
            System.out.println("3.查看当前进程信息");
            System.out.println("0.退出");
            System.out.println("**************************");
            int num=sc.nextInt();
            switch (num){
                case 1:
                    String name;
                    int proirity;
                    int runtime;
                    int arrivaltime;
                    System.out.println("请输入进程名:");
                    name=sc.next();
                    System.out.println("请输入进程优先级:");
                    proirity=sc.nextInt();
                    System.out.println("进程进程运行时间:");
                    runtime=sc.nextInt();
                    System.out.println("进程进程到达时间:");
                    arrivaltime=sc.nextInt();
                    pcbs=create.createPcb( pcbs,name,proirity,runtime,arrivaltime);
                    break;
                case 2:
                    Psch.dispatchMenu(pcbs);
                    break;
                case 3:
                    create.check(pcbs);
                    break;
                case 0:
                    count1=0;
                    break;
                default:
                    System.out.println("输入错误,请重新输入!");
                    break;
            }
        }
    }

4.调度界面函数

实现主窗口类下的一个主要函数:调度界面函数。

代码如下:

public static void dispatchMenu(ArrayList<PCB> pcbs){
        Scanner sc=new Scanner(System.in);
        Algorithm al=new Algorithm();    //实例化算法类
        int count=1;
        while(count==1){
            PriorityQueue<PCB> useCase=al.initQueue(pcbs);
            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("5.高响应比优先算法:");
            System.out.println("0.退出");
            int num=sc.nextInt();
            switch(num){
                case 1:
                    al.FCFS(useCase);
                    break;
                case 2:
                    al.SJF(useCase);
                    break;
                case 3:
                    //定义时间片
                    System.out.println("请输入时间片大小:");
                    int timeR=sc.nextInt();
                    al.RR(useCase,timeR);
                    break;
                case 4:
                    al.PR(useCase);
                    break;
                case 5:
                    al.HRRN(useCase);
                    break;
                case 0:
                    count=0;
                    break;
                default:
                    System.out.println("输入错误,请重新输入!");
                    break;
            }
        }
    }
}

5.算法类及其调度算法通用函数

1.算法类数据

package os.test1;
import java.util.*;

public class Algorithm {
    private PCB min=null;     //满足运行条件的进程
    private int num=0;       //一批进程周转时间和
    private int start=0;    //更新系统开始时间
    private double nums=0;   //一批带权周转时间
    private int count=0;     //统计一批进程的进程个数
    private static Create create=new Create();  //实例化,以方便创建和增加进程

2.所有进程调度可用通用函数

代码如下:

//将传来的PCB数组转化成先以到达时间从小到大,再以进程大小从小到大排序而成的队列并返回
    public PriorityQueue<PCB> ArrivalAscPri(ArrayList<PCB> pcbs) {
        PriorityQueue<PCB> arrAscQueue = new PriorityQueue<>((x1,x2)->
        {return x1.arrivaltime!=x2.arrivaltime?x1.arrivaltime-x2.arrivaltime
                :x1.runtime-x2.runtime;});
        while (!pcbs.isEmpty())
            arrAscQueue.add(pcbs.remove(0));
        return arrAscQueue;
    }

    //复制数组中的对象,并使用ArrivalAscPri函数返回优先级队列
    public PriorityQueue<PCB> initQueue(ArrayList<PCB>pcbs) {
        ArrayList<PCB> useCase = new ArrayList<PCB>();
        for (PCB cur : pcbs){
            PCB temp=new PCB(cur.name,cur.priority,cur.runtime,cur.arrivaltime);
            useCase.add(temp);
        }
        PriorityQueue<PCB> arrAscQueue=ArrivalAscPri(useCase);
        return arrAscQueue;
    }

    //end进程已经运行完,打印这个进程的信息
    public void endPrint(PCB end){
        System.out.println("进程名:"+end.name+",优先级:"+end.priority+",运行时间:"+end.runtime+",到达时间:"+
                end.arrivaltime+",开始时间:"+end.starttime+",结束时间:"+end.endtime+",周转时间:"+end.turntime+
                ",带权周转时间:"+end.dturntime);
    }

    //所有进程都运行完了,打印平均周转时间和平均带权周转时间并重置数据成员参数
    public void endFun(){
        System.out.println("平均周转时间:"+(double)this.num/this.count+",平均带权周转时间:"+this.nums/this.count);
        this.start=0;
        this.nums=0;
        this.count=0;
        this.num=0;
        this.min=null;
    }
   //进程已经结束,更新进程开始时间,结束时间,周转时间,带权周转时间,更新nums,num,start(下一 
    个进程开始时间)
    public void operation(){
        start = start > min.arrivaltime ? start : min.arrivaltime;
        min.starttime = start;
        min.endtime = min.starttime + min.runtime;
        min.turntime = min.endtime - min.arrivaltime;
        min.dturntime = (double) min.turntime / min.runtime;
        endPrint(min);
        num += min.turntime;
        nums += min.dturntime;
        start = min.endtime;
    }

6.进程调度算法函数

1.先来先服务算法(FCFS)

代码如下:

//先来先服务算法
    public void FCFS(PriorityQueue<PCB> arrAscQueue){
        while(!arrAscQueue.isEmpty()){
            min=arrAscQueue.remove();  //直接根据优先级队列顺序打印(先到先打印,同时到运行时间小先打印)
            operation();
            count++;
        }
        this.endFun();   //所有进程调度完成
    }

2.短作业优先算法(SJF)

代码如下:

//短作业优先算法
    public void SJF(PriorityQueue<PCB>arrAscQueue){
        //根据运行时间大小实现短作业优先级就绪队列
        PriorityQueue<PCB> arrivedAscQueue=new PriorityQueue<PCB>((x1,x2)->{return x1.runtime-x2.runtime;});
        while(!arrAscQueue.isEmpty()||!arrivedAscQueue.isEmpty()){
            //如果就绪队列为空并且start进程可开始运行时间小于arrAscQueue的队首元素到达时间,就进一个入就绪队列
            if(arrivedAscQueue.isEmpty()&&!arrAscQueue.isEmpty()&&start<arrAscQueue.peek().arrivaltime)
                arrivedAscQueue.add(arrAscQueue.remove());
           if(!arrivedAscQueue.isEmpty()) {   //运行就绪队列的队首元素
                min=arrivedAscQueue.remove();
                operation();
                count++;
            }
            //到达时间小于下一进程开始时间就进就绪队列
            while(!arrAscQueue.isEmpty()&&start>=arrAscQueue.peek().arrivaltime){
                arrivedAscQueue.add(arrAscQueue.remove());
            }
        }
        endFun();
    }

3.时间片轮转算法(RR)

代码如下:

//根据剩余运行时间运行完min进程打印并设置其值和数据成员值
    //只用于时间片轮转算法
    public void operationRR(int minTime){
        min.endtime = start + minTime;
        min.turntime = min.endtime - min.arrivaltime;
        min.dturntime = (double) min.turntime / min.runtime;
        endPrint(min);
        num += min.turntime;
        nums += min.dturntime;
        start = min.endtime;
    }
    //时间片轮转算法
    public void RR(PriorityQueue<PCB>arrAscQueue,int timeR) {
        PriorityQueue<PCB> newArrAscQueue= new PriorityQueue<PCB>((x1,x2)->{return x1.newarrival-x2.newarrival;});
       //如果有,先把前面先到达的进程并且连续运行时间小于时间片的运行完
        while(!arrAscQueue.isEmpty()&&arrAscQueue.peek().runtime<=timeR){
            min=arrAscQueue.remove();
            operation();
            count++;
        }
        while(!arrAscQueue.isEmpty()||!newArrAscQueue.isEmpty()){
            while(!arrAscQueue.isEmpty()&&start>=arrAscQueue.peek().arrivaltime)
                newArrAscQueue.add(arrAscQueue.remove());
            //找出符合算法的进程运行
            if(newArrAscQueue.isEmpty()||
                    (!arrAscQueue.isEmpty()&&newArrAscQueue.peek().newarrival>=arrAscQueue.peek().arrivaltime)
            )
                min=arrAscQueue.remove();
            else
                min=newArrAscQueue.remove();
            if(min.runtime==min.newruntime) {
                start=start>min.arrivaltime?start:min.arrivaltime;
                min.starttime = start;
            }
            int minTime=Math.min(min.runtime,min.newruntime);
            if(minTime<=timeR){
                operationRR(minTime);
                count++;
            }
            else{
                start+=timeR;
                min.newruntime-=timeR;
                min.newarrival+=(newArrAscQueue.size()+1)*timeR;
                newArrAscQueue.add(min);
            }
        }
        endFun();
    }

4.动态优先级算法(PR)

代码如下:

//比较器,实现动态优先级队列
    public class DynamicPriDecComparator implements Comparator<PCB> {
        @Override
        public int compare(PCB o1, PCB o2) {
            return (start - o2.arrivaltime + o2.priority) - (start - o1.arrivaltime + o1.priority);
        }
    }
    //更新动态优先级(start会改变)
    public void updatePR(PriorityQueue<PCB> PRqueue){
        PriorityQueue<PCB> temp=new PriorityQueue<>(new DynamicPriDecComparator());
        while(!PRqueue.isEmpty())
            temp.add(PRqueue.remove());
        while(!temp.isEmpty())
            PRqueue.add(temp.remove());
    }
    public void PR(PriorityQueue<PCB> arrAscQueue){
        //优先级从大到小为高到低
        PriorityQueue<PCB> newpriDecQueue= new PriorityQueue<PCB>(new DynamicPriDecComparator());
        while(!arrAscQueue.isEmpty()||!newpriDecQueue.isEmpty()){
            //只有进程可开始时间大于arrAscQueue队首元素到达时间才进就绪队列
            while(!arrAscQueue.isEmpty()&&start>=arrAscQueue.peek().arrivaltime)
                newpriDecQueue.add(arrAscQueue.remove());
            //选出符合运行条件的进程
            if(newpriDecQueue.isEmpty())
                min=arrAscQueue.remove();
            else
                min=newpriDecQueue.remove();
            operation();
            count++;
            updatePR(newpriDecQueue);
        }
        endFun();
    }

5.高响应比算法(HRRN)

代码如下:

//😊比较器,实现高响应比优先级队列
    public class RpDecComparator implements Comparator<PCB> {
        @Override
        public int compare(PCB o1, PCB o2) {
            return (double)(start - o2.arrivaltime )/o2.runtime > (double)(start - o1.arrivaltime )/o1.runtime
                    ?1:-1;
        }
    }

    //更新响应比并更新队列
    public void updateHRR(PriorityQueue<PCB> HRRqueue){
        PriorityQueue<PCB> temp=new PriorityQueue<>(new RpDecComparator());
        while(!HRRqueue.isEmpty())
            temp.add(HRRqueue.remove());
        while(!temp.isEmpty())
            HRRqueue.add(temp.remove());
    }
    //高响应比优先算法
    public void HRRN(PriorityQueue<PCB> arrAscQueue) {
        PriorityQueue<PCB> newrpDecQueue= new PriorityQueue<PCB>(new RpDecComparator());
        while(!arrAscQueue.isEmpty()||!newrpDecQueue.isEmpty()){
            while(!arrAscQueue.isEmpty()&&start>=arrAscQueue.peek().arrivaltime)
                newrpDecQueue.add(arrAscQueue.remove());
            if(newrpDecQueue.isEmpty())
                min=arrAscQueue.remove();
            else
                min=newrpDecQueue.remove();
            operation();
            updateHRR(newrpDecQueue);   //更新响应比并更新队列
            count++;
        }
        endFun();
    }

总结

已经测试过了,和各位伙伴一起进步!