当前位置: 首页 > 知识库问答 >
问题:

最短剩余时间优先:Java 多线程

归松
2023-03-14

我正在尝试在 java 中模拟 CPU 调度算法并使用多线程。我已经成功地实施了FCFS(先到先得)和SJF(最短的工作优先)。但问题是当我开始想到SRTF(最短剩余时间优先)时,它是SJF的一种先发制人的形式。我正在使用以下模型:

  • CPU的线程,它有一个CLOCK变量,它每100ms保持滴答声(一个简单的时钟增量)。我有一个布尔值is的;标志,用于在开始执行之前检查CPU是否可用。
  • 长期调度程序(LTS)的线程,它将进程从进程列表推送到就绪队列。
  • 短期调度程序(STS)的线程,它从ReadyQueue获取一个进程并将其分配给CPU。
  • 一旦STS从ReadyQueue中删除了一个进程以供执行,该进程就会检查CPU的is

我手头有进程列表以及它们的到达和爆发时间。这是确定的,直到我模拟非抢占式调度(FCFS和SJF)。但是当我尝试SRTF时,我无法找到抢占当前正在运行的进程线程的方法。

对于 SRTF,我知道从 ReadyQueue 中选择下一个进程的方法。一旦我从队列中选择一个进程,我就可以尝试将 isAvailable 标志设置为 false,但是我如何知道最初正在执行哪个线程?由于我没有使用太多同步黑白线程,因此我将有多个进程使用 CPU 线程。它变得有点混乱。请帮忙。谢谢!

这是进程的代码:

enum State {ARRIVED, WAITING, READY, RUNNING, EXECUTED}
public class Process implements Runnable
{
    int pid;
    int arrTime;
int burstTime;
int priority;
long startTime;
long endTime;
State procState = null;

Process(int pid, int arrTime, int burstTime, int priority)
{
    this.pid = pid;
    this.arrTime = arrTime;
    this.burstTime = burstTime;
    this.priority = priority;
    this.procState = State.ARRIVED;
    this.startTime = 0;


    this.endTime = 0;    /* I also considered adding a timeElapsedUnderExecution
 attribute to the process. So I can check after every cycle if the CPU is still available
 and keep incrementing the time elapsed. Once the timeElapsed becomes same as burstTime, i
 stop the process. Or if after a cycle, the CPU is not available, i know from where to
 resume my Process. Is this the way to go ? */

    }

boolean isReady()
{
    if((this.arrTime <= CPU.CLOCK) && (this.procState == State.ARRIVED))
        return true;
    else return false;
}

@Override
public void run() {
    // TODO Auto-generated method stub
    if(this.procState == State.READY)
        this.procState = State.WAITING;

    while(!CPU.isAvailable());

    try 
    {
        this.procState = State.RUNNING;
        System.out.println("Process " + pid + " executing...");
        this.startTime = CPU.CLOCK;
        System.out.println("Process " + this.pid + ": Begins at " + this.startTime);
        Thread.sleep(this.burstTime * 100);
        this.endTime = CPU.CLOCK;
        System.out.println("Process " + this.pid + ": Ends at " + this.endTime);
        this.procState = State.EXECUTED;

    }
    catch (InterruptedException e) 
    {
        // TODO Auto-generated catch block
        System.out.println("Interrupted: " + pid);
        e.printStackTrace();
    }
    }
}

CPU的代码:

    import java.util.LinkedList;
    import java.util.Queue;

    public class CPU implements Runnable

{
    static Long CLOCK = new Long(0);
    static LinkedList<Process> ReadyQ = new LinkedList<Process>();
private static boolean isAvailable = true;
static boolean done = false;

public static boolean isAvailable() {
    return isAvailable;
}

public static void setAvailable(boolean isAvailable) {
    CPU.isAvailable = isAvailable;
}

static void incrementCLOCK()
{
    LTS.checkArrival();
    CPU.CLOCK++;
    try {
        Thread.sleep(100);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    System.out.println("Clock Tick: " + CPU.CLOCK);
}

@Override
public void run() {
    // TODO Auto-generated method stub
    System.out.println("CPU starts.!!!");
    while(CPU.done != true)
        synchronized(CPU.CLOCK)
        {
            incrementCLOCK();
            }
    }
}

LTS 的代码:

public class LTS implements Runnable 
{
    private static Process[] pList = null;
    private final int NUM;
    static Integer procStarted;
    static Integer procFinished;
    static boolean STSDone = false;


LTS(Process[] pList, int num)
{
    this.NUM = num;
    LTS.pList = pList;
}

static void checkArrival()
{
    if(pList == null) return;
    for(int i = 0; i < pList.length; i++)
        if(pList[i].isReady())
        {
            pList[i].procState = State.READY;
            System.out.println("Process " + pList[i].pid + " is now ready.");
            CPU.ReadyQ.add(pList[i]);
        }
}

@Override
public void run() {
    // TODO Auto-generated method stub
    System.out.println("Long Term Scheduler starts.!!!");
    while(LTS.STSDone != true)
    {
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    System.out.println(LTS.STSDone);
    System.out.println("LTS ends.!!!");
        CPU.done = true;
    }
}

共有1个答案

陶宜民
2023-03-14

问题1是您的共享状态不是线程安全的。即使是布尔值这样的简单事情也需要正确的线程原语来确保跨线程的可见性(又名“易失性”)。

 类似资料:
  • 该算法是SJF调度的抢先版本。 在SRTF中,过程的执行可以在一段时间后停止。 在每个进程到来时,短期调度程序在可用进程列表和正在运行的进程中以最少的剩余突发时间安排进程。 一旦所有进程都在就绪队列中可用,就不会执行抢占,并且该算法将作为SJF调度工作。 当进程从执行中被移除并且下一个进程被调度时,进程的上下文被保存在进程控制块中。 该PCB在下一次执行该过程时被访问。 示例 在这个例子中,有五个

  • 我使用最短剩余时间优先算法(SRTF)来计算流程的平均等待时间和周转时间。 我想以如下所示的表格格式打印结果。 这里AT=到达时间,TT=周转时间,WT=等待时间。但是由于过程3和4的完成时间不可能,出现了一些错误。这是我的代码: 我犯了什么错误?请纠正我。

  • 如果它们是具有以下数据的两个过程,甘特图应该如何?(SRTF 调度) 进程到达突发 P1 0 17 P2 1 16 那么,进程P1会先完成,然后P2会开始执行……还是P1必须等待16毫秒?

  • 亲爱的AnyLogic社区, 我是AnyLogic的新手,希望你们能帮助我! 我有一个简单的流程模型,由多个源、队列、抢占、延迟、释放和接收器(流程模型)组成。我建模的系统是一个服务器容量问题。我有不同的服务时间和有限的服务器容量的代理,我感兴趣的KPI是在资源池耗尽时没有得到适当服务的客户的数量。目前,我允许客户在使用所有资源时在队列块超时,但这并不能准确地表示系统在实际生活中的表现。 在现实中

  • 接下来的最短剩余时间如何解决这个问题?“最短作业优先”的抢占式版本。 我了解选择完成前剩余时间最少的过程来执行。但是,如果到达的新进程的突发时间与当前正在执行的进程的剩余完成时间完全相同,会发生什么情况? 如果一个新进程到达,其突发时间与当前执行的进程相同(如本例所示),那么当前执行的过程是否继续? 我的理解正确吗?提前谢谢你。

  • 我熟悉最短进程下一个调度算法(SJF),它是一种非抢先算法。但是,该算法一次只能处理一个突发时间最小的进程。是否可以一次修改为“下一个最短流程2”? 所以对于这里提到的例子: 第一行表示进程总数。随后的行表示进程ID、到达时间、突发时间。 一次有两个流程的SJF计划将按如下方式工作: 这里 Idle表示当前有多少处理器空闲。在这种情况下,有2个处理器。可以观察到,在时间< code>t=4,有2个