1

割り当てのセマフォを扱うプログラムをJavaで書いています。私はセマフォと同時実行のアイデアにまだ慣れていません。問題の説明は次のとおりです。

  1. ブール値のベクトル V[]。Pi がクリティカル セクションを使用する必要がある場合、V[i] は「True」です。
  2. プロセスがクリティカル セクションに入るのをブロックするためのバイナリ セマフォ B[] のベクトル: B[i] はセマフォ ブロッキング プロセス Pi になります。
  3. クリティカル セクションを使用するために、ブロックされたプロセスを起動する必要がある場合は常に、特別なスケジューラ プロセス SCHED が使用されます。
  4. SCHED は、特別なセマフォ S を待機することによってブロックされます
  5. プロセス Pi がクリティカル セクションに入る必要がある場合、プロセス Pi は V[i] を「True」に設定し、セマフォ S にシグナルを送信してから、セマフォ B[i] を待機します。
  6. SCHED がブロック解除されるたびに、V[i] が「True」である最小のインデックス i を持つプロセス Pi が選択されます。その後、プロセス Pi は B[i] を通知することによって起動され、SCHED はセマフォ S をブロックすることによってスリープ状態に戻ります。
  7. プロセス Pi がクリティカル セクションを離れると、プロセス S に信号が送られます。

これは私のコードです:

import java.util.concurrent.Semaphore;

public class Process extends Thread {
    static boolean V[];
    int i;
    static Semaphore B[]; //blocking semaphore
    static Semaphore S;
    private static int id;
    static int N;
    static int insist = 0;

    public static void process (int i, int n) {
       id = i;
       N = n;
       V = new boolean[N];
    }

    private void delay () {
       try {
        sleep (random(500));
        }
        catch (InterruptedException p) {
        }
    }

    private static int random(int n) {
        return (int) Math.round(n * Math.random() - 0.5);
    }

    private void entryprotocol(int i) {
         V[Process.id] = true;
         int turn = N;
         while (V[Process.id] == true && turn == N) {
           System.out.println("P" + Process.id + " is requesting critical section");
           signal(S);
         }
        critical(Process.id);
        wait(B[Process.id]);
        V[Process.id] = false;
        }



   private void wait(Semaphore S) {
       if (Process.id > 0) {
        Process.id--;
      } else {
        //add Process.id to id.queue and block
        wait(B[Process.id]);
       }
   }

     private void signal(Semaphore S) {
         if (B[Process.id] != null) {
          Sched(Process.id);
        } else {
          Process.id++; //remove process from queue
          critical(Process.id); //wakes up current process
         }
     }

    private void critical(int i) {
        System.out.println("P" + Process.id + " is in the critical section");
        delay();
        exitprotocol(i);
     }

    private void exitprotocol(int i) {
        System.out.println("P" + Process.id + " is leaving the critical section");
        V[id] = false;
        signal(S);
    }

     public void Sched(int i) {
         if (B[Process.id] == null) {
        signal(B[Process.id]);
        }
        wait(S);
     }

     public void run() {
         for (int i = 0; i < 5; i++) {
            Sched(i);
           entryprotocol(Process.id);
           try {
              wait(Process.id);
          }
           catch (InterruptedException p) {
            }
          signal(S);
        }
         }


    public static void main (String[] args) {
        int N = 5;

        Process p[] = new Process[N];

        for (int i = 0; i < N; i++) {
        p[i] = new Process();
        p[i].start();
        }
        }
   }

ここでのロジックは正しいと思いますが、多くのエラーが発生しています (スレッド "Thread-1" java.lang.NullPointerException の例外など)。私が間違っていることを明らかにし、助けを提供してもらえますか。大歓迎です!

4

1 に答える 1

4

おそらく、セマフォNPE配列を初期化していないという事実が原因ですが、適切なスタックトレースがないと言いにくいです。

2 つのアドバイス:

1) クラス変数に : B N S V よりも意味のある名前を付けたいと思うかもしれません。

2) コードを書く前に、ホワイト ボード上でクラス モデルを把握します。一部の静的フィールドと同じ名前のセマフォを取るメソッドがあります。プログラム内のオブジェクトの関係は? わからない場合は、プログラムもわかっていない可能性があります。

于 2012-04-10T05:10:39.100 に答える