Home

LinkWorld Algorithm Blog

25 Nov 2017

操作系统处理机调度算法模拟实现-Notzuonotdied

操作系统处理机调度算法模拟实现

简介

  多道程序设计中,经常是若干个进程同时处于就绪状态,为了使系统中的各进程有条不紊地运行,必须选择某种调度策略,以选择一个进程占用处理机。

思路分析

  由于本实验是按照处理机调度算法模拟实现处理机的调度,与真正的处理机调度过程不完全相同,比如没有实现中断,进程的运行也不是真正的运行,而是在屏幕上打印其运行时间等。

大致思路:

  • 建立三个队列:PCB队列,就绪队列,完成队列。
    • PCB队列:保存将进入系统的进程。(由于没有实现中断,所以将进入系统运行的进程必须在程序运行前给出)。
    • 就绪队列:到达进程进入系统的时间,将该进程放入就绪队列,等待调度。
    • 完成队列:将“运行”完的进程放入完成队列。
  • 进程运行过程是在屏幕上打印相关信息。
    • 使用轮转算法调度的进程应打印的信息包括:进程占用处理机序列,该进程每次占用处理机的开始时间与结束时间。
  • 统计出进程的周转时间T和带权周转时间W。

大致流程图

这里写图片描述

实现

public class OSRR {
    public static void main(String[] args) {
        new RR();
    }
}

class RR {
    private Queue<RRBean> PCBQueue;
    private LinkedList<RRBean> ReadyQueue;
    private Queue<RRBean> CompleteQueue;
    // 定义时间片的长度
    private static final int SLICETIME = 4;
    // 定义总的运行时间
    private int time;

    RR() {
        time = 0;
        InitQueue();
        InitBean();
        StartProcess();
        showResult();
    }

    private void StartProcess() {
        System.out.println("PCB进程数" + PCBQueue.size());
        StringBuilder sb = new StringBuilder();
        sb.append("运行过程:");
        while (true) {
            // 是否所有进程运行完
            if (PCBQueue.size() == 0 && ReadyQueue.size() == 0) {
                // 如果所有进程都运行完了,就终止程序
                break;
            }
            // 是否有新的进程进入系统
            for (RRBean r : PCBQueue) {
                // 新的进程进入就绪队列
                if (r.arrive_time <= time) {
                    ReadyQueue.addFirst(r);
                    PCBQueue.remove(r);
                    break;
                }
            }

            // 就绪队列不为空的时候
            if (ReadyQueue.size() != 0) {
                // 取出一个进程运行
                RRBean r = ReadyQueue.poll();
                r.run_time += SLICETIME;
                int temp = time;
                // 如果时间片用完之后,
                if (r.run_time >= r.time) {
                    time += r.time - r.run_time + SLICETIME;
                    r.endTime = time;
                    // 该进程已经完成了
                    CompleteQueue.offer(r);
                } else {
                    time += SLICETIME;
                    // 该进程没有完成
                    ReadyQueue.offer(r);
                }
                System.out.println("进程号:" + r.id +
                        ",本次开始时间:" + temp + ",本次结束时间:" + time);
                sb.append(r.id);
                sb.append("->");
            } else {
                ++time;
            }
        }
        sb.delete(sb.length() - 2, sb.length());
        System.out.println(sb.toString());
    }

    private void showResult() {
        System.out.println("××××××××最后的结果:××××××××");
        for (RRBean rrBean : CompleteQueue) {
            System.out.println("进程号:" + rrBean.id + ",周转时间为:" +
                    (rrBean.endTime - rrBean.arrive_time) + ",平均周转时间:" +
                    (float) (rrBean.endTime - rrBean.arrive_time) / rrBean.time);
        }
    }


    private void InitQueue() {
        PCBQueue = new LinkedList<>();
        ReadyQueue = new LinkedList<>();
        CompleteQueue = new LinkedList<>();
    }

    private void InitBean() {
        File file = new File("./src/Schedule/rr1.txt");
        BufferedReader br = null;
        String read;
        try {
            System.out.println("进程ID\t到达时间\t估计运行时间\t优先级");
            br = new BufferedReader(new FileReader(file));
            while ((read = br.readLine()) != null) {
                RRBean rrBean = new RRBean();
                rrBean.init(read);
                PCBQueue.offer(rrBean);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            System.out.println("文件不存在");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

class RRBean {
    //进程号
    int id;
    //进程状态  0-Ready,  1-Run,  2-Finish
    int status;
    //进程到达时间
    int arrive_time;
    //估计运行时间
    int time;
    //已运行时间
    int run_time;
    //等待时间
    int wait_time;
    //优先级
    int priority;
    // 结束时间
    int endTime;

    void init(String initString) {
        List<String> num = new ArrayList<>();
        Pattern pattern = Pattern.compile("-*\\d+(\\.\\d+)?");
        Matcher matcher = pattern.matcher(initString);
        while (matcher.find()) {
            num.add(matcher.group());
        }
        StringBuilder sb = new StringBuilder();
        for (String string : num) {
            sb.append(string);
            sb.append("\t\t");
        }
        System.out.println(sb.toString());
        this.id = Integer.parseInt(num.get(0));
        this.arrive_time = Integer.parseInt(num.get(1));
        this.time = Integer.parseInt(num.get(2));
        this.priority = Integer.parseInt(num.get(3));
        this.status = 0;
        this.run_time = 0;
        this.wait_time = 0;
    }
}

情况1

  备注:进程ID、到达时间、估计运行时间、优先级

0     2   30    2
1     2   60    4
2     15   15    0
3     26   28    5
4     80   19    1
5     90   8     7

  输出结果:(备注:时间片为10)

进程ID	到达时间	估计运行时间	优先级
0		2		30		2		
1		2		60		4		
2		15		15		0		
3		26		28		5		
4		80		19		1		
5		90		8		7		
PCB进程数6
进程号:0,本次开始时间:2,本次结束时间:12
进程号:1,本次开始时间:12,本次结束时间:22
进程号:2,本次开始时间:22,本次结束时间:32
进程号:3,本次开始时间:32,本次结束时间:42
进程号:0,本次开始时间:42,本次结束时间:52
进程号:1,本次开始时间:52,本次结束时间:62
进程号:2,本次开始时间:62,本次结束时间:67
进程号:3,本次开始时间:67,本次结束时间:77
进程号:0,本次开始时间:77,本次结束时间:87
进程号:4,本次开始时间:87,本次结束时间:97
进程号:5,本次开始时间:97,本次结束时间:105
进程号:1,本次开始时间:105,本次结束时间:115
进程号:3,本次开始时间:115,本次结束时间:123
进程号:4,本次开始时间:123,本次结束时间:132
进程号:1,本次开始时间:132,本次结束时间:142
进程号:1,本次开始时间:142,本次结束时间:152
进程号:1,本次开始时间:152,本次结束时间:162
运行过程:0->1->2->3->0->1->2->3->0->4->5->1->3->4->1->1->1
××××××××最后的结果:××××××××
进程号:2,周转时间为:52,平均周转时间:3.4666667
进程号:0,周转时间为:85,平均周转时间:2.8333333
进程号:5,周转时间为:15,平均周转时间:1.875
进程号:3,周转时间为:97,平均周转时间:3.4642856
进程号:4,周转时间为:52,平均周转时间:2.7368422
进程号:1,周转时间为:160,平均周转时间:2.6666667

情况2

     备注:进程ID、到达时间、估计运行时间、优先级

0     0   4    2
1     1   3    4
2     2   4    0
3     3   2    5
4     4   4    1

  输出结果:(备注:时间片为1)

进程ID	到达时间	估计运行时间	优先级
0		0		4		2		
1		1		3		4		
2		2		4		0		
3		3		2		5		
4		4		4		1		
PCB进程数5
进程号:0,本次开始时间:0,本次结束时间:1
进程号:1,本次开始时间:1,本次结束时间:2
进程号:2,本次开始时间:2,本次结束时间:3
进程号:3,本次开始时间:3,本次结束时间:4
进程号:4,本次开始时间:4,本次结束时间:5
进程号:0,本次开始时间:5,本次结束时间:6
进程号:1,本次开始时间:6,本次结束时间:7
进程号:2,本次开始时间:7,本次结束时间:8
进程号:3,本次开始时间:8,本次结束时间:9
进程号:4,本次开始时间:9,本次结束时间:10
进程号:0,本次开始时间:10,本次结束时间:11
进程号:1,本次开始时间:11,本次结束时间:12
进程号:2,本次开始时间:12,本次结束时间:13
进程号:4,本次开始时间:13,本次结束时间:14
进程号:0,本次开始时间:14,本次结束时间:15
进程号:2,本次开始时间:15,本次结束时间:16
进程号:4,本次开始时间:16,本次结束时间:17
运行过程:0->1->2->3->4->0->1->2->3->4->0->1->2->4->0->2->4
××××××××最后的结果:××××××××
进程号:3,周转时间为:6,平均周转时间:3.0
进程号:1,周转时间为:11,平均周转时间:3.6666667
进程号:0,周转时间为:15,平均周转时间:3.75
进程号:2,周转时间为:14,平均周转时间:3.5
进程号:4,周转时间为:13,平均周转时间:3.25

  输出结果:(备注:时间片为4)

进程ID	到达时间	估计运行时间	优先级
0		0		4		2		
1		1		3		4		
2		2		4		0		
3		3		2		5		
4		4		4		1		
PCB进程数5
进程号:0,本次开始时间:0,本次结束时间:4
进程号:1,本次开始时间:4,本次结束时间:7
进程号:2,本次开始时间:7,本次结束时间:11
进程号:3,本次开始时间:11,本次结束时间:13
进程号:4,本次开始时间:13,本次结束时间:17
运行过程:0->1->2->3->4
××××××××最后的结果:××××××××
进程号:0,周转时间为:4,平均周转时间:1.0
进程号:1,周转时间为:6,平均周转时间:2.0
进程号:2,周转时间为:9,平均周转时间:2.25
进程号:3,周转时间为:10,平均周转时间:5.0
进程号:4,周转时间为:13,平均周转时间:3.25

Til next time,
LinkWorld at 18:56

scribble