2012-05-01 2 views
0

OS 과정을위한 CPU 스케줄링 시뮬레이터 프로젝트를하고 있습니다. 프로그램은 두 개의 스레드, 즉 생산자 스레드와 소비자 스레드로 구성되어야합니다. 생성자 스레드는 시스템에서 프로세스를 생성하는 생성자와 여러 프로세스를 선택하고이를 ReadyQueue 유형의 버퍼 (소비자 및 생산자가 공유 객체)에 넣는 장기 스케줄러를 포함합니다. 소비자 스레드는 큐에서 프로세스를 가져와 스케줄링 알고리즘을 시작하는 단기 스케줄러를 포함합니다. 스레드를 사용하지 않고 전체 프로그램을 작성했지만 제대로 작동했지만 이제는 스레드를 추가해야하고 스레드를 사용하지 않아서 필요한 스레드를 구현하기 위해 아래에 표시된 코드를 수정하는 방법을 보여줄 수 있는지 잘 알고 있습니다.생산자/소비자 스레드가 결과를 제공하지 않습니다.

public class Consumer extends Thread{ 

    ReadyQueue Buffer = new ReadyQueue(20); 
    Vector<Process> FinishQueue = new Vector<Process>(); 
    MLQF Scheduler ; 
    public Consumer(ReadyQueue buffer){ 
     Buffer = buffer; 
     Scheduler = new MLQF(Buffer,FinishQueue); // An instance of the multi-level Queue Scheduler 
    } 

    @Override 
    public void run() { 
     int count = 0;   // A counter to track the number of processes 

     while(true){ 
      synchronized(this){ 
       Scheduler.fillQueue(Buffer); // Take contents in Buffer and put them in a separate queue in the scheduler 
         Scheduler.start();    // Start Scheduling algorithm 
       count++; 
      } 
      if(count >= 200) // If counter exceeds the maximum number of processes thread must yeild 
       yield(); 
      notify();    // Notify Producer thread when buffer is empty 
     } 
    } 

    public void setReadyQueue(ReadyQueue q){ 
     Buffer = q; 
    } 
} 

이 메인 스레드는 다음과 같습니다 :

public class test { 

    public static void main(String[] args) throws FileNotFoundException,InterruptedException {  
     ReadyQueue BoundedBuffer = new ReadyQueue(20); 
     Producer p = new Producer(BoundedBuffer); 
     Consumer c = new Consumer(p.getReadyQueue()); 
     p.start(); 
     System.out.println("Ready Queue: "+p.getReadyQueue()); 
     p.join(); 
     c.start(); 
     c.join(); 
     } 
} 

가 사전에 감사

public class Producer extends Thread{ 

    ReadyQueue Buffer = new ReadyQueue(20); // Shared Buffer of size 20 between consumer and producer 
    JobScheduler js = new JobScheduler(Buffer); 

    private boolean systemTerminate = false; // Flag to tell Thread that there are no more processes in the system 

    public Producer(ReadyQueue buffer) throws FileNotFoundException{ 
     Buffer = buffer; 
     Generator gen = new Generator(); // Generator generates processes and put them in a vector called memory  
     gen.writeOnFile(); 
    } 

    @Override 
    public void run() { 

     synchronized(this){ 
      js.select(); // Job Scheduler will select processes to be put in the Buffer 

      Buffer = (ReadyQueue) js.getSelectedProcesses(); 

      while(!Buffer.isEmpty()){  
       try { 
        wait();  // When Buffer is empty wait until getting notification 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
       systemTerminate = js.select(); 
       Buffer = (ReadyQueue) js.getSelectedProcesses(); 
       if(systemTerminate)  // If the flag's value is true the thread yields 
        yield(); 
      } 
     } 
    } 

    public ReadyQueue getReadyQueue(){ 
     return Buffer; 
    } 
} 

이 소비자 클래스 구현 :

다음은 생산자 클래스 구현입니다.

답변

1

코드에 대한 한 가지 문제점은 다중 스레드 제작자/소비자 모델에서 일반적인 버그로 인해 어려움을 겪고 있다는 것입니다. 이어야하며 wait() 전화를 사용하십시오. while을 사용하십시오. 예를 들어 :

try { 
    // we must do this test in a while loop because of consumer race conditions 
    while(!Buffer.isEmpty()) { 
     wait();  // When Buffer is empty wait until getting notification 
     ... 
    } 
} catch (InterruptedException e) { 
    e.printStackTrace(); 
} 

문제는 당신이, 당신은 할 수있다 notify 스레드를 소비하는 여러 스레드를 가지고 있지만 다음 다른 스레드를 통해 오는 만든 그냥 추가 된 항목을 큐에서 제거합니다. 스레드가 통지 된 후 WAIT 대기열에서 RUN 대기열로 이동되면 대개 대기열의 끝에 배치되고 this에서 동기화 대기중인 다른 스레드 뒤에 배치됩니다.

자세한 내용은 내 documentation about this을 참조하십시오.

+0

답장을 보내 주셔서 감사합니다. 회색. 이 버그의 원인이되는 스레드에 대해 좀 더 자세히 설명해 주시겠습니까? 소비자 또는 생산자? 또는 스레드를 처음 사용하는 경우이 문제를 해결하는 방법을 보여줄 수도 있습니다. – Samantha

+0

또한'notify' 메소드는'synchronized' 블록 내에 있어야합니다. – Gray

+0

버그는 소비자의 'while (true)'루프 @Samantha에 있습니다. 내 답변에서 제공 한 링크에는 모든 세부 정보가 있습니다. 소비자와 같은 조건에서 기다리면 기다리고 있던 상태를 다시 테스트해야합니다. – Gray

관련 문제