0

OSコースのCPUスケジューリングシミュレータプロジェクトを行っています。プログラムは、プロデューサースレッドとコンシューマースレッドの2つのスレッドで構成されている必要があります。プロデューサースレッドには、システムでプロセスを生成するジェネレーターと、多数のプロセスを選択してReadyQueueタイプのBufferというオブジェクト(コンシューマーとプロデューサーによる共有オブジェクト)に配置する長期スケジューラーが含まれます。コンシューマースレッドには、キューからプロセスを取得してスケジューリングアルゴリズムを開始する短期スケジューラーが含まれています。スレッドを使用せずにプログラム全体を作成しましたが、正しく機能しましたが、スレッドを追加する必要があり、スレッドを使用したことがないので、必要なスレッドを実装するために以下に示すコードを変更する方法を誰かに教えてもらえれば幸いです。

Producerクラスの実装は次のとおりです。

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

これはConsumerクラスの実装です。

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

前もって感謝します。

4

1 に答える 1

1

あなたのコードの問題の 1 つは、マルチスレッドのプロデューサー/コンシューマー モデルでよくあるバグに悩まされていることです。呼び出しを見て回る必要があります。例えば:whilewait()

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

詳細については、これに関する私のドキュメントを参照してください。

于 2012-05-01T19:50:59.647 に答える