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

本文介绍了时间片轮转法的概念,系统如何按照先来先服务策略组织就绪队列,并讨论了时间片大小对性能的影响。通过代码演示了轮转法的执行过程,展示了时间片设置不当可能导致其退化为先来先服务算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

轮转法(时间片轮转法)

简介

在轮转算法中,系统根据先来先服务策略,将所有的就绪进程排成一个就绪队列。并可设置每隔一定的时间间隔即可产生一次中断,激活系统中的进程调度程序,完成一次调度,将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.*;

/**
 * @Author XuJiAn
 * @Time 2022/4/24
 */
public class RR {

    /**
     * 初始化操作
     * @param list 原本的进程数据源程集合
     * @param readyQueue 就绪队列
     * @return map list与readyQueue结果集映射*
     */
    public static Map<String, Object> initProcess(List<Process> list, Deque<Process> readyQueue) {
        //将模拟进程按进程的进入时间排序如果进入时间相同按工作时间排序
        list.sort(new Comparator<Process>() {
            @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<String, Object> map = new HashMap<>();
        map.put("list", list);
        map.put("readyQueue", readyQueue);
        return map;
    }

    /**
     * 轮转算法核心方法
     * @param list 原本的进程数据源程集合
     * @param finishList 结果集
     * @param readyQueue 就绪队列
     * @param time 时间
     * @return finishList 结果集
     */
    public static List<Process> doProcess(List<Process> list, List<Process> finishList, Deque<Process> readyQueue, int time) {
        int timeSlice = 1;
        //要处理的进程
        Process process = null;
        //存进程名
        List<String> 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<Process> list=new ArrayList<Process>();
        list.add(p1);
        list.add(p2);
        list.add(p3);
        list.add(p4);
        list.add(p5);
        //完成的进程放入这个集合
        List<Process> finish=new ArrayList<Process>();
        //就绪队列
        Deque<Process> readyQueue=new ArrayDeque<Process>();

        //进行初始化
        Map<String, Object> map = RR.initProcess(list, readyQueue);
        list = (List<Process>) map.get("list");
        readyQueue= (Deque<Process>) map.get("readyQueue");
        List<Process> 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<Process>() {
            @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退化为先来先服务算法
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小徐404

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值