/ / Temps restant le plus court en premier: multithreading Java - java, multithreading, cpu, planification, simulation

Le temps restant le plus court en premier: multithreading Java - java, multithreading, cpu, planification, simulation

J'essaie de simuler des algorithmes de planification du processeuren java et j'utilise le multithreading. J'ai implémenté avec succès FCFS (First Come First Serve) et SJF (Shortest Job First). Mais le problème est quand je commence à penser à SRTF (Shortest Remaining Time First), qui est une forme préventive de SJF. J'utilise le modèle suivant:

  • Un thread pour le processeur, qui a un CLOCK variable, qui continue de tourner (un incrément d'horloge simple) tous les 100ms. j'ai un boolean isAvailable; indicateur pour que les processus vérifient si la CPU est disponible avant de commencer l'exécution.
  • Un thread pour le planificateur à long terme (LTS), qui pousse le processus de la liste des processus vers une file d'attente disponible.
  • Un thread pour le planificateur à court terme (STS), qui extrait un processus de la ReadyQueue et l'assigne à la CPU.
  • Une fois qu'un processus est supprimé de la ReadyQueue par STS pour exécution, le processus vérifie la isAvailable drapeau de la CPU. Si true, il positionne le drapeau sur false et commence son exécution (pour laquelle je ne fais que mettre le fil en veille pour (100 * burstTime) ms comme il ne s’agit que d’une simulation). Sinon, le processus reste occupé à attendre: while(CPU.isAvailable != true);.

J'ai la liste des processus avec leurarrivée et temps de rafale avant la main. Je peux simuler un ordonnancement non préemptif (FCFS et SJF). Mais comme j'essaye de SRTF, je suis incapable de trouver un moyen de préempter le thread de processus en cours d'exécution.

Pour SRTF, je connais la voie à suivre pour sélectionner le processus suivant dans ReadyQueue. Je peux essayer de régler le isAvailable drapeau à false une fois que je sélectionne un processus dans la file d'attente, mais ensuiteComment puis-je savoir quel thread était en train de s'exécuter? Et comme je n’utilise pas beaucoup de threads de synchronisation n / b, j’aurai plusieurs processus utilisant la CPU fil. Cela devient un peu foiré. S'il vous plaît aider. Merci!

C'est le code pour un processus:

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

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

Le code pour 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;
}
}

Réponses:

0 pour la réponse № 1

Le problème numéro 1 est que votre état partagé n'est pas thread-safe. Même des choses simples comme les booléens ont besoin de primitives de threading correctes pour assurer la visibilité entre les threads (aka "volatile").