2012-10-01 12 views
5

मैं जावा में सीपीयू शेड्यूलिंग एल्गोरिदम अनुकरण करने की कोशिश कर रहा हूं और मल्टीथ्रेडिंग का उपयोग कर रहा हूं। मैंने सफलतापूर्वक एफसीएफएस (फर्स्ट आओ फर्स्ट सेव) और एसजेएफ (सबसे कम नौकरी फर्स्ट) लागू किया है। लेकिन समस्या यह है कि जब मैं एसआरटीएफ (सबसे कम समय का पहला समय) के बारे में सोचना शुरू करता हूं जो एसजेएफ का एक पूर्ववत रूप है।सबसे कम समय शेष: जावा मल्टीथ्रेडिंग

  • सीपीयू के लिए एक धागा है, जो एक CLOCK चर, जो टिक टिक रहता है (एक साधारण घड़ी वेतन वृद्धि) हर 100ms है: मैं निम्नलिखित मॉडल का उपयोग कर रहा हूँ। प्रक्रियाओं के लिए मेरे पास boolean isAvailable; ध्वज है यह जांचने के लिए कि क्या CPU निष्पादन शुरू करने से पहले उपलब्ध है या नहीं।
  • लांग टर्म शेड्यूलर (एलटीएस) के लिए एक थ्रेड, जो प्रक्रिया सूची से प्रक्रिया को तैयार कतार में धक्का देता है।
  • शॉर्ट टर्म शेड्यूलर (एसटीएस) के लिए एक थ्रेड, जो रेडीक्यूयू से एक प्रक्रिया लेता है और इसे सीपीयू को असाइन करता है।
  • निष्पादन के लिए एसटीएस द्वारा तैयार क्यूई से एक प्रक्रिया को हटा दिए जाने के बाद, प्रक्रिया isAvailable सीपीयू के ध्वज की जांच करती है। यदि true, यह ध्वज को झूठी पर सेट करता है और इसके निष्पादन को शुरू करता है (जिसके लिए मैं केवल (100 * burstTime) ms के लिए धागा सो रहा हूं क्योंकि यह केवल एक सिमुलेशन है)। अन्यथा, प्रक्रिया बस व्यस्त रहने में व्यस्त रहता है: while(CPU.isAvailable != true);

मेरे पास उनके आगमन और हाथ से पहले समय के साथ प्रक्रियाओं की सूची है। यह तब तक ठीक है जब तक मैं गैर-प्रीपेप्टिव शेड्यूलिंग (एफसीएफएस और एसजेएफ) को अनुकरण नहीं कर रहा हूं। लेकिन जैसा कि मैं एसआरटीएफ के लिए प्रयास करता हूं, मैं वर्तमान में चल रहे प्रक्रिया थ्रेड को प्रीमिट करने का कोई तरीका नहीं ढूंढ पा रहा हूं।

एसआरटीएफ के लिए, मुझे रेडीक्यूयू से अगली प्रक्रिया का चयन करने के लिए आगे की ओर पता है। एक बार जब मैं कतार से एक प्रक्रिया का चयन करता हूं, तो मैं 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(); 
    } 
    } 
} 

सीपीयू के लिए कोड:

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

को अधिक कोड, विशेष रूप से सीपीयू दिखाने की आवश्यकता है। – jtahlborn

+0

मैंने 'CPU' और 'LTS' के लिए कोड जोड़ा है। – akaHuman

उत्तर

0

समस्या नंबर 1 है कि आपके साझा किया जाता है राज्य थ्रेड-सुरक्षित नहीं है। बुलियन जैसे साधारण चीजों को धागे (उर्फ "अस्थिर") में दृश्यता सुनिश्चित करने के लिए सही थ्रेडिंग प्राइमेटिव की आवश्यकता होती है।

+0

क्या आप कृपया उस पर विस्तार कर सकते हैं? धन्यवाद! – akaHuman

+1

विषय विस्तृत करने के लिए विषय बहुत बड़ा है, मुझे डर है। बहुत से लोग इस पुस्तक को पढ़ने की सलाह देते हैं: http://www.amazon.com/Java-Concurrency- अभ्यास- ब्रायन-Goetz/dp/0321349601 –

संबंधित मुद्दे