栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

操作系统-轮转法(时间片轮转法)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

操作系统-轮转法(时间片轮转法)

轮转法(时间片轮转法) 简介

在轮转算法中,系统根据先来先服务策略,将所有的就绪进程排成一个就绪队列。并可设置每隔一定的时间间隔即可产生一次中断,激活系统中的进程调度程序,完成一次调度,将CPU分配给队首的进程,令其执行。当该进程的时间片结束,或者该进程在时间片上提前结束,系统在将CPU分配给队首的进程。由此,可以保证就绪队列的所有进程在一个确定的时间片内,都能获得一次CPU执行

进程切换的情况
  1. 在一个时间片内,时间片用尽进程没有结束,这时就要把当前运行的进程放入就绪队列的队尾,就绪队列队首的进程获取到CPU并开始执行

  2. 在一个时间片内,进程提前结束,这时候此进程运行结束,并且就绪队列的第一进程获取到CPU开始执行。

时间片确定问题

时间片的确定对性能有很大的影响,比如时间片很小,就会出现进程上下文之间频繁切换很影响性能。如果时间片过大,轮转法就退化为了先来先服务算法。

代码演示

首先创建一个Process类来模拟进程,没有lombok包的手动生成getter setter和构造方法即可

package com.xu.demo.ytu;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Process {
    //作业名
    private String ProcessName;
    //到达时间
    private int InterTime;
    //运行时间
    private int WorkTime;
    //开始时间
    private int StartTime;
    //完成时间
    private int FinishTime;
    //周转时间
    private int TurnTime;
    //带权周转时间
    private float PowerTurnTime;
    //时间标识判断是否在时间片上运行结束
    private int TimeFlag;
    //用于接收用户输入并赋值
    public Process(String processName, int interTime, int workTime) {
        ProcessName = processName;
        InterTime = interTime;
        WorkTime = workTime;
        TimeFlag= workTime;
    }
    @Override
    public String toString() {
        return
                "作业名:" + ProcessName  +
                "   到达时间:" + InterTime +
                "   运行时间:" + WorkTime +
                "   开始时间:" + StartTime +
                "   完成时间:" + FinishTime +
                "   周转时间:" + TurnTime +
                "   带权周转时间:" + PowerTurnTime
                ;
    }
}

论转算法核心部分代码(这里的时间片为1,可在修改timeSlice进行修改)

package com.xu.demo.ytu;

import java.util.*;


public class RR {

    
    public static Map initProcess(List list, Deque readyQueue) {
        //将模拟进程按进程的进入时间排序如果进入时间相同按工作时间排序
        list.sort(new Comparator() {
            @Override
            public int compare(Process p1, Process p2) {
                int num = p1.getInterTime() - p2.getInterTime();
                return num == 0 ? p1.getWorkTime() - p2.getWorkTime() : num;
            }
        });
        //进程数据源集合移除第一个放入就绪队列
        readyQueue.add(list.remove(0));
        //操作后的集合存入hashmap返回
        Map map = new HashMap<>();
        map.put("list", list);
        map.put("readyQueue", readyQueue);
        return map;
    }

    
    public static List doProcess(List list, List finishList, Deque readyQueue, int time) {
        int timeSlice = 1;
        //要处理的进程
        Process process = null;
        //存进程名
        List rqNames=new ArrayList<>();
        if (!readyQueue.isEmpty()) {

            process = readyQueue.removeFirst();
            //获取开始时间
            if (process.getStartTime()==0&&!process.getProcessName().equals("A")) {
                process.setStartTime(time);
            }
            process.setTimeFlag(process.getTimeFlag() - timeSlice);
            //判断finish是否还有进程
            if (process.getTimeFlag() <= 0) {
                if (!list.isEmpty()) {
                    readyQueue.addLast(list.remove(0));
                }
            }
        }
        //进程在时间片上已运行的时间
        time = time + timeSlice;
        for (Process item : readyQueue) {
            rqNames.add(item.getProcessName());
        }
//        System.out.println("在 ["+(time-timeSlice)+" - "+time+")时间段--"+process.getProcessName()+"----进程正在运行--"+"--就绪队列的进程----"+rqNames);
        //进程在时间片上如果没有结束
        if (process.getTimeFlag() > 0) {
            if (!list.isEmpty()) {
                readyQueue.addLast(list.remove(0));
                readyQueue.addLast(process);
            } else {
                readyQueue.addLast(process);
            }
        }
        //进程在时间片上正常结束
        if (process.getTimeFlag() == 0) {
            process.setFinishTime(time);
            process.setTurnTime(process.getFinishTime() - process.getInterTime());
            process.setPowerTurnTime((float) process.getTurnTime() / (float) process.getWorkTime());
            finishList.add(process);
        }
        //进程会在时间片没结束的时候提前完成
        //在这个时间片内继续处理下一个进程
        if (process.getTimeFlag() < 0) {
            //这时候process.getTimeFlag()为负数
            //此时的time + process.getTimeFlag()就是进程结束时刻
            time = time + process.getTimeFlag();
            process.setFinishTime(time);
            process.setTurnTime(process.getFinishTime() - process.getInterTime());
            process.setPowerTurnTime((float) process.getTurnTime() / (float) process.getWorkTime());
            finishList.add(process);
        }
        System.out.println("在 ["+(time-timeSlice)+" - "+time+")时间段--"+process.getProcessName()+"----进程正在运行--"+"--就绪队列的进程----"+rqNames);
        //终止条件
        if (readyQueue.isEmpty()) {
            return finishList;
        }
        //进行递归
        return RR.doProcess(list, finishList, readyQueue, time);
    }
}

测试类

package com.xu.demo.ytu;

import java.util.*;

public class TestRR {
    public static void main(String[] args) {
        Process p1=new Process("A",0,4);
        Process p2=new Process("B",1,3);
        Process p3=new Process("C",2,4);
        Process p4=new Process("D",3,2);
        Process p5=new Process("E",4,4);
        List list=new ArrayList();
        list.add(p1);
        list.add(p2);
        list.add(p3);
        list.add(p4);
        list.add(p5);
        //完成的进程放入这个集合
        List finish=new ArrayList();
        //就绪队列
        Deque readyQueue=new ArrayDeque();

        //进行初始化
        Map map = RR.initProcess(list, readyQueue);
        list = (List) map.get("list");
        readyQueue= (Deque) map.get("readyQueue");
        List result = RR.doProcess(list, finish, readyQueue, 0);
        System.out.println("进程先后完成结果集;");
        for (Process process : result) {
            System.out.println(process);
        }
        System.out.println("进程原顺序结果集;");
        result.sort(new Comparator() {
            @Override
            public int compare(Process p1, Process p2) {
                int num = p1.getInterTime() - p2.getInterTime();
                return num == 0 ? p1.getWorkTime() - p2.getWorkTime() : num;
            }
        });
        for (Process process : result) {
            System.out.println(process);
        }
        
    }
}

运行结果

如果时间片为4退化为先来先服务算法

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/835769.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号