【问题标题】:Round Robin scheduling in javajava中的循环调度
【发布时间】:2016-10-21 05:30:18
【问题描述】:

我正在尝试实现循环调度算法。但是到目前为止我所做的代码只考虑了突发时间。我还需要考虑流程的到达时间。我有一个 time_chart 数组,我用它来存储当前正在执行的进程的编号。但是如果当前没有进程正在执行(即如果选定的进程已完成执行并且下一个进程尚未到达。),则应将值 0 插入到 time_chart 数组中。

我已将突发时间和到达时间存储在二维数组中:

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

和变量q中的时间量子。以下是我的代码:

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]);
}

当前它会选择下一个进程,即使它还没有到达。因此,我需要检查下一个过程是否已经到达。我尝试使用proc[sel_proc][0] &lt;= k 进行检查,但似乎没有用。我的意思是我没有得到任何输出。我想不出另一种方法来检查下一个过程是否已经到达。如果下一个进程尚未到达,我如何检查这一点并将值 0 放入数组中?

【问题讨论】:

  • 建议:使用Listclass Proc { int arrival; int remainingTime} 作为您的时间表。处理新条目的添加和已完成条目的删除变得更加容易。
  • @AdrianColomitchi。我不需要删除这些进程,因为这些详细信息用于稍后计算waiting timeturnaround time。我已经完成了那部分。
  • 您能否提供您要解决的问题的文字描述。 Round Robin 用于在多个资源之间分配负载。你的资源是什么?是否还有其他仅按资源请求的调度问题?也许某些请求比其他请求使用了更多的资源。
  • @PathagamaKuruppugeTharindu 我回答你的问题了吗?如果是,请接受,如果不是,请发表评论。

标签: java algorithm


【解决方案1】:

虽然您可以仅使用数组来完成此操作,但如果您创建一个类结构来存储进程信息并使用两个Queues,您可能会发现逻辑更容易。第一个Queue 是按到达时间排序的进程列表,第二个Queue 是当前正在执行的进程。

您可以按照这些思路对您的处理进行建模

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;
    }
}

然后创建一个队列调用未计划的进程(或任何看起来合适的)并将进程添加到按到达时间排序的队列中。 Queue&lt;Process&gt; = new LinkedList&lt;&gt;()

现在在您的循环中,每次您只需检查队列的头部并查看进程的到达时间是否等于或大于当前时间。如果将其从队列中删除并将其添加到调度程序队列的头部。 LinkedList&lt;Process&gt; = new LinkedList&lt;&gt;()

您总是从调度程序队列中删除头进程并更新进程的执行时间。确保不要超过突发时间,即执行时间总是增加量子或突发时间 - 执行时间,取决于哪个更小。更新后,如果执行时间小于burstTime,则将进程添加回调度器队列。

请记住,如果进程上的剩余时间小于该时间量,则当前时间不会增加时间量。

【讨论】:

    【解决方案2】:

    如果不是单个int 跟踪当前正在运行的进程,这个问题会简单得多,而是使用所有列表。一个好的选择是保留一个有序列表,其中正在运行的进程位于最前面,其他进程按照它们将来应该运行的顺序进行。然后,您始终可以通过旋转列表来运行下一个进程。更新每个量程的列表很简单。使所有这些选项变得简单的 Java 集合称为 Deque

    类似这样的:

    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());
      }
    }
    

    注意,我使用了更合理的名称和 Java 约定。您选择的名称和数据类型有点可怕。正如其他人所说,最好在class 中对进程的到达和突发时间进行分组。

    【讨论】:

      【解决方案3】:

      其实你应该看看进程的到达时间是否小于等于下一个即将到来的时间。所以,你应该检查proc[sel_proc][0] &lt;= k + 1。特别是,你应该做的唯一改变是你的 if which 而不是

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

      应该变成:(如果剩余burst时间不为零且其到达时间早于或等于下一次,即k + 1)

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

      更重要的是,确保您的最后一个有效时间单位是 total_time - 1 而不是 total_time 本身。此外,您的到达时间是基于 0 还是基于 1,这些都是您必须小心的极端情况。

      【讨论】:

        【解决方案4】:

        你打算用你的算法来安排什么。我从来没有听说过有人会进行时间切片,除非是在实现操作系统时。

        时间片在操作系统级别起作用,因为操作系统可以选择它想要在 CPU 上运行的(符合条件的)进程/线程,并且因为操作系统基本上可以在任何指令处停止线程并将 CPU 注册表刷新到缓存.如果每个任务都可以分解为非常小的工作单元(“CPU”指令),则此原则仅适用于代码。这样,如果您有 100 个任务,每个任务由 100 个单元组成,并且有 4 个处理器内核,您就可以实现自己的时间切片算法(但我不建议这样做)。

        传统上,如果您有多个并发任务,您将使用线程数等于 CPU 内核数(或更多任务具有 IO)的线程池,并且您只需在任务到达时将它们排队,然后让操作系统担心时间切片。

        【讨论】:

        • 看来他并没有真正实现调度程序。这是一个调度模拟,可能用于学校项目。
        猜你喜欢
        • 2011-01-03
        • 2015-06-19
        • 1970-01-01
        • 1970-01-01
        • 2023-04-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-05
        相关资源
        最近更新 更多