简体   繁体   English

Java中的循环调度

[英]Round Robin scheduling in java

I'm trying to implement Round Robin scheduling algorithm. 我正在尝试实现Round Robin调度算法。 But the code I have done so far only consider the burst time. 但是到目前为止,我所做的代码仅考虑了突发时间。 I also need to consider the arrival time of the process too. 我还需要考虑流程的到达时间。 I have a time_chart array which I'm using to store the number of the process which is currently executing. 我有一个time_chart数组,用于存储当前正在执行的进程号。 But if no process is currently executing (that is if selected process has finished executing and next process has not arrived.), value 0 should be inserted into the time_chart array. 但是,如果当前没有任何进程在执行(即所选进程已完成执行且下一个进程尚未到达。),则应将0插入到time_chart数组中。

I have stored burst time and arrival time in a 2D array as: 我将突发时间和到达时间存储在2D数组中为:

//proc[][0] is the AT array
//proc[][1] is the BT array

and Time Quantum in variable q. 和时间量子在变量q中。 Below is my code: 下面是我的代码:

int time_chart[] = new int[total_time];
int sel_proc = 1;
int current_q = 0;

for (int k = 0; k < total_time; k++) {

    //Assign selected process to current time in the Chart
    time_chart[k] = sel_proc;

    //Decrement Remaining Time of selected process by 1 since it has been assigned the CPU for 1 unit of time
    proc[sel_proc - 1][1]--;

    //Updating value of sel_proc for next iteration
    current_q++;

    if (current_q == q || proc[sel_proc - 1][1] == 0)//If Time slice has expired or the current process has completed execution
    {
        current_q = 0;
        //This will select the next valid value for sel_proc
        for (int j = 1; j <= n; j++) {
            sel_proc++;
            if (sel_proc == (n + 1)) {
                sel_proc = 1;
            }
            if (proc[sel_proc - 1][1] != 0) {
                break;
            }
        }
    }
}

// print timeline for testing
for (i = 0; i < total_time; i++) {
System.out.println("Time " + i + ": " + time_chart[i]);
}

currently it will select the next process even though it has not arrived yet. 当前,即使尚未到达,它也会选择下一个进程。 Therefore, I need to check if the next process has arrived or not. 因此,我需要检查下一个过程是否已经到来。 I tried using proc[sel_proc][0] <= k to check this but it didn't seem to work. 我尝试使用proc[sel_proc][0] <= k进行检查,但似乎无法正常工作。 By that I mean I didn't get any output. 我的意思是我没有得到任何输出。 I can't think of another way to check if the next process has arrived or not. 我想不出另一种方法来检查下一个过程是否已经到来。 How can I check this and put value 0 into the array if the next process has not arrived? 如果下一个进程尚未到达,如何检查此值并将值0放入数组?

Although you can accomplish this using only arrays you may find the logic easier if you create a class structure to store the process information and use two Queues . 尽管您可以仅使用数组来完成此操作,但是如果创建一个用于存储过程信息并使用两个Queues的类结构,则可能会发现逻辑更容易。 The first Queue being a list of processes ordered by arrival time and the second Queue the processes that are currently being executed. 第一个Queue是按到达时间排序的进程列表,第二个Queue是当前正在执行的进程。

You can model you process something along these lines 您可以按照以下思路建模处理某些事物

private static class Process {
    public final int id;
    public final int burstTime;
    public final int arrivalTime;
    public int executionTime;

    public Process(int id, int burstTime, int arrivalTime) {
        super();
        this.id = id;
        this.burstTime = burstTime;
        this.arrivalTime = arrivalTime;
    }
}

Then create a Queue call unscheduled processes (Or what ever seems appropriate) and add the processes to that queue ordered by arrival time. 然后创建一个队列调用未计划的进程(或者看起来合适的队列),并将这些进程按到达时间排序添加到该队列中。 Queue<Process> = new LinkedList<>()

Now during your loop every time you just check the head of the queue and see if the process' arrival time is equal or greater than the current time. 现在,每次循环时,您只需检查队列的开头,看看进程的到达时间是否等于或大于当前时间。 If it is remove it from the queue and add it to the head of scheduler queue. 如果是,请从队列中将其删除,并将其添加到调度程序队列的头部。 LinkedList<Process> = new LinkedList<>()

You always remove the head process from the scheduler queue and update the execution time of the process. 您总是从计划程序队列中删除头进程,并更新该进程的执行时间。 Make sure not to go beyond burst time, ie execution time is always increased by the quantum OR burstTime - executionTime, depending on which is smaller. 确保不要超过猝发时间,即执行时间总是以量子OR猝发时间-executeTime的形式增加,具体取决于哪个较小。 After the update, if the execution time is less then the burstTime, add the process back to the scheduler queue. 更新后,如果执行时间少于burstTime,则将进程添加回调度程序队列。

Remember the the current time will not be increased by quantum, if the remaining time on the process was less than the quantum. 请记住,如果该过程中的剩余时间少于量子时间,则当前时间不会因量子时间而增加。

This problem is much simpler if rather than a single int tracking the currently running process, you use a list of all. 如果您使用所有列表而不是单个int跟踪当前正在运行的进程,则此问题要简单得多。 A good choice is to keep an ordered list where the running process is at the head, and the others follow in the order they should run in the future. 一个好的选择是保留一个有序列表,其中正在运行的程序位于最前面,而其他程序则按照它们将来应该运行的顺序进行操作。 Then you can always get the next process to run by rotating the list. 然后,您总是可以通过旋转列表来运行下一个进程。 It's simple to update the list for each quantum. 更新每个量子的列表很简单。 A Java collection that makes all these options easy is called a Deque . 使所有这些选项变得容易的Java集合称为Deque

Something like this: 像这样:

Deque<Integer> running = new ArrayDeque<>();
for (int quantum = 0; quantum < totalDuration; ++quantum) {
  // Add new arrivals to the list of running processes.
  // Note that if the processes are pre-sorted by arrival time,
  // this loop can be made more efficient. This assumes no sorting.
  for (int process = 1; process <= processCount; ++process) {
    if (arrivalTime[process] == quantum)
      running.addLast(process); // Use addFirst if new procs should run immediately.
  }
  if (running.isEmpty())
    timeChart[quantum] = 0; // Nothing to run
  else {
    // Select the process now at the head.
    int selectedProcess = running.getFirst();

    // Decrement the running process's burst time. If it's done, remove
    // it from the running list.
    if (--burstTime[selectedProcess] == 0) 
      running.removeFirst();

    // Record the run for this quantum.        
    timeChart[quantum] = selectedProcess;

    // Rotate the previous head to the tail of the list for next quantum.
    if (running.size() > 1)
      running.addLast(running.removeFirst());
  }
}

Note I've used more rational names and Java conventions. 注意我使用了更多的合理名称和Java约定。 Your choice of names and data types is a bit hideous. 您对名称和数据类型的选择有点令人毛骨悚然。 As others have said, it would be still better to group arrival and burst times for a process in a class . 正如其他人所说,这将是最好还是组抵达和破裂时间在一流程class

Actually, you should see whether the arrival time of the process is less than or equal the next upcoming time . 实际上,您应该查看进程的到达时间是否小于或等于下一个即将到来的时间 So, you should check proc[sel_proc][0] <= k + 1 . 因此,您应该检查proc[sel_proc][0] <= k + 1 In particular, the only change that you should make is your if which instead of 特别是,您唯一应做的更改就是您的if而不是

if (proc[sel_proc - 1][1] != 0) {
    break;
}

should become: (if the remaining burst time is not zero and its arrival time is before or equal the next time, ie k + 1) 应该变为:(如果剩余的突发时间不为零,并且其到达时间在下一次之前或等于下一次,即k + 1)

if (proc[sel_proc - 1][1] != 0 && proc[sel_proc][0] <= k + 1) {
        break;
}

More importantly , make sure that your last valid time unit is total_time - 1 and not total_time itself. 更重要的是 ,请确保您的最后一个有效时间单位是total_time-1,而不是total_time本身。 Furthermore, are your arrival times 0-based or 1-based, these are corner cases that you have to be careful about. 此外,您的到达时间是从0开始还是从1开始,这是您必须注意的极端情况。

What do you plan to schedule with your algorithm. 您计划使用算法计划什么。 I have never heard of anyone that does time slicing, except when implementing an operating system. 我从来没有听说过有人进行时间分片,除非实现操作系统。

Time slicing works at an OS level because the OS can choose which (of the eligible) processes/threads it wants to run on the CPU, and because the OS can basically stop a thread at any instruction and flush CPU registries to cache. 时间分片在OS级别上起作用,因为OS可以选择要在CPU上运行的(合格的)进程/线程,并且OS基本上可以在任何指令下停止线程并刷新CPU注册表以进行缓存。 This principle will only work in code, if each task can be broken down to very small units of work ('CPU' instructions). 如果可以将每个任务分解为非常小的工作单元(“ CPU”指令),则该原理仅适用于代码。 That way if you have 100 tasks consisting of 100 units each, and a 4 processor cores, you can implement your own time slicing algorithm (but I would not recommend it). 这样,如果您有100个任务(每个任务包含100个单元)和4个处理器核心,则可以实现自己的时间分片算法(但我不建议这样做)。

Traditionally, if you have multiple concurrent tasks, you would use a threadpool with thread count equal to the number of CPU cores (or more it the tasks have IO), and you would simply queue the tasks as they arrive, and let the OS worry about time slicing. 传统上,如果您有多个并发任务,则将使用线程计数等于CPU核心数量(或更多的任务具有IO)的线程池,并且只需在任务到达时将它们排队,并让操作系统担心关于时间切片。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM