2012-10-01 8 views
5

JavaでCPUスケジューリングアルゴリズムをシミュレートしようとしていますが、マルチスレッドを使用しています。 FCFS(First Come First Serve)とSJF(Shortest Job First)の導入に成功しました。しかし問題は、私がSJFの先制型であるSRTF(最短残存時間)を考え始めるときです。 CPU用最短残存時間最初:Javaマルチスレッド

  • スレッド、刻々と過ぎて続けるCLOCK変数、(単純なクロック増分)ごと100msがあります 私は、次のモデルを使用しています。実行を開始する前にCPUが使用可能かどうかを確認するプロセスには、boolean isAvailable;フラグがあります。
  • プロセスリストから準備完了キューにプロセスをプッシュするLong Term Scheduler(LTS)用のスレッド。
  • 短期スケジューラ(STS)用のスレッド。これは、ReadyQueueからプロセスを取り出してCPUに割り当てます。
  • 実行のためにSTSによってReadyQueueからプロセスが削除されると、プロセスはCPUのisAvailableフラグをチェックします。 trueの場合は、フラグをfalseに設定して実行を開始します(これはちょうどシミュレーションのため(100 * burstTime) msのためにスレッドをスリープさせています)。さもなければ、プロセスはちょうど待っているのを忙しく保ちます:while(CPU.isAvailable != true);

私はプロセスのリストとその前の到着とバースト時間を手にしています。 非プリエンプティブスケジューリング(FCFSとSJF)をシミュレートするまでは問題ありません。しかし、SRTFを試してみると、現在実行中のプロセススレッドをプリエンプトする方法を見つけることができません。

SRTFの場合、ReadyQueueから次のプロセスを選択する方法が分かります。キューからプロセスを選択したら、フラグをfalseに設定することができますが、どのスレッドが元々実行されていたのかを知るにはどうすればよいですか?同期のb/wスレッドをほとんど使用していないので、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; 
    } 
} 
+0

さらにコード、特にCPUを表示する必要があります。 – jtahlborn

+0

私は 'CPU'と 'LTS'のコードを追加しました。 – akaHuman

答えて

0

問題番号1は、共有ということです状態はスレッドセーフではありません。ブール値のような単純なものであっても、スレッド間の可視性を保証するために正しいスレッド化プリミティブが必要です(別名「volatile」)。

+0

それを詳しく教えてもらえますか?ありがとう! – akaHuman

+1

被写体が大きすぎてここで詳述できない、恐れ入ります。多くの人がこの本を読むことをお勧めします:http://www.amazon.com/Java-Concurrency-Practice-Brian-Goetz/dp/0321349601 –

関連する問題