食事する哲学者の問題 解法の例

食事する哲学者の問題

出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2022/06/04 23:33 UTC 版)

解法の例

次のコードは、Pascalで書かれた解法の例である(モニタを使用)。

PROGRAM d_p;
   CONST
      DoomsDay = FALSE;

   MONITOR dining_philosophers;  // モニタ宣言開始
      CONST
         Eating   = 0;   
         Hungry   = 1;
         Thinking = 2;
      VAR
         i       : INTEGER; // ループ変数初期化
         state   : ARRAY [0..4] OF INTEGER; // Eating、Hungry、Thinking
         can_eat : ARRAY [0..4] OF CONDITION; // 哲学者それぞれに対応
         // 箸がそろうまで、空腹の哲学者を置く

      PROCEDURE test(k : INTEGER);
      BEGIN
         IF (state[k] = Hungry)
            AND (state[(k+4) MOD 5] <> Eating)
            AND (state[(k+1) MOD 5] <> Eating) THEN
         BEGIN
            state[k] := Eating;
            SIGNALC(can_eat[k]); // 待ち状態の者がいればその状態を終了させる
         END; 
      END; 

      PROCEDURE pickup(i: INTEGER);
      BEGIN
         state[i] := Hungry;
         WRITELN('philosopher ',i,' hungry');
         test(i); // 隣の人は食事中か? 
         IF state[i] <> Eating THEN
            WAITC(can_eat[i]);  // 隣人の食事が終わるまで待つ
         WRITELN('philosopher ',i,' eating');
      END; 

      PROCEDURE putdown(i : INTEGER);
      BEGIN
         state[i] := Thinking;
         WRITELN('philosopher ',i,' thinking');
         test( (i+4) MOD 5); // 左の隣人が食事するチャンスを与える
         test( (i+1) MOD 5); // 右の隣人が食事するチャンスを与える
      END;  

   BEGIN // モニタを初期化
      FOR i := 0 TO 4 DO state[i] := Thinking;
   END;  // モニタ定義の終わり

   PROCEDURE philosopher(i : INTEGER);
   BEGIN
      REPEAT
         pickup(i);  // 箸をとる
         putdown(i); // 箸をおく
      UNTIL DoomsDay;
   END; 

BEGIN // 主プログラム
   COBEGIN  // 5つのプロセスを同時に開始
      philosopher(0); philosopher(1); philosopher(2);
      philosopher(3); philosopher(4);
   COEND;
END

次のコードは、Javaで書かれた解法の例である(セマフォを使用)。

import java.util.concurrent.Semaphore;
import java.util.Random;
import java.util.Vector;

public class Philosopher extends Thread
{
    private static final Random rand = new Random();
    private static int event=0;
    private static String binary="";
    private int id;
    private Semaphore sem;
    private static Vector<Object[]> vector = new Vector<Object[]>();

    public Philosopher(int i, Semaphore s)
    {
        id = i;
        sem = s;
        binary = binary + "0";
    }

    private void busy()
    {
        try
        {
            sleep(rand.nextInt(1000));
        } catch (InterruptedException e){}
    }

    private void thinking()
    {
        String str = "Philosopher " + id + " is thinking";
        vector.add( this.addToObject(System.currentTimeMillis(), event , str) );
        event++;
        busy();
    }

    private void eating()
    {
        String str ="Philosopher " + id + " is hungry and is trying to pick up his chopsticks";
        vector.add( this.addToObject(System.currentTimeMillis(), event , str) );
        event++;
        busy();
        str = "Philosopher " + id + " is eating";
        this.oneToBinary(id);
        vector.add( this.addToObject(System.currentTimeMillis(), event , str) );
        event++;
        busy();
        str = "Philosopher " + id + " finished eating, and puts away his chopsticks";
        this.zeroToBinary(id);
        vector.add( this.addToObject(System.currentTimeMillis(), event , str) );
        event++;
    }

    private Object[] addToObject(long t, int i,String s ){
        Object[] o = new Object[4];
        o[3] = s;
        o[2] = i;
        o[1] = binary;
        o[0] = t;
        return o;
    }

    private void oneToBinary(int i){
        binary = binary.substring(0,i) + "1" + binary.substring(i+1);
    }

    private void zeroToBinary(int i){
        binary = binary.substring(0,i) + "0" + binary.substring(i+1);
    }

    @Override
    public void run()
    {
        for (int i = 0; i < 10; ++i)
        {
            thinking();
            try
            {
                sem.acquire();
            } catch (InterruptedException e){}
            eating();
            sem.release();
        }
    }

    public static void main(String[] args)
    {
        final int N = 5;
        Semaphore sem = new Semaphore(N, true);
        Philosopher[] philosopher = new Philosopher[N];

        // 哲学者を生成
        for (int i = 0; i < N; i++) {
          philosopher[i] = new Philosopher(i, sem);
          philosopher[i].start();
        }
        // 完了を待ち合わせる
        for (int i = 0; i < N; i++) {
          try {
            philosopher[i].join();
          } catch(InterruptedException ex) {
            return;
          }
        }

        for (int i = 0; i < vector.size(); i++) {
            Object[] o = vector.get(i);
            System.out.printf("%d %d %s %s\n", o[0], o[2], o[1], o[3]);
        }
    }
}

  1. ^ Dijkstra, Edsger W. EWD-1000. E.W. Dijkstra Archive. Center for American History, University of Texas at Austin. (original; transcription)
  2. ^ J. Díaz; I. Ramos (1981). Formalization of Programming Concepts: International Colloquium, Peniscola, Spain, April 19–25, 1981. Proceedings. Birkhäuser. pp. 323 , 326. ISBN 978-3-540-10699-9. https://books.google.co.jp/books?id=pl4VJKQlcG4C&redir_esc=y&hl=ja 
  3. ^ Hoare, C. A. R. (2004年). “Communicating Sequential Processes”. usingcsp.com (originally published in 1985 by Prentice Hall International). 2012年7月16日閲覧。
  4. ^ 海外での例
  5. ^ Dijkstra, Edsger W. EWD-310. E.W. Dijkstra Archive. Center for American History, University of Texas at Austin. (original; transcription)
  6. ^ Dijkstra, Edsger W. EWD-123. E.W. Dijkstra Archive. Center for American History, University of Texas at Austin. (original; transcription)


「食事する哲学者の問題」の続きの解説一覧




固有名詞の分類


英和和英テキスト翻訳>> Weblio翻訳
英語⇒日本語日本語⇒英語
  

辞書ショートカット

すべての辞書の索引

「食事する哲学者の問題」の関連用語

食事する哲学者の問題のお隣キーワード
検索ランキング

   

英語⇒日本語
日本語⇒英語
   



食事する哲学者の問題のページの著作権
Weblio 辞書 情報提供元は 参加元一覧 にて確認できます。

   
ウィキペディアウィキペディア
All text is available under the terms of the GNU Free Documentation License.
この記事は、ウィキペディアの食事する哲学者の問題 (改訂履歴)の記事を複製、再配布したものにあたり、GNU Free Documentation Licenseというライセンスの下で提供されています。 Weblio辞書に掲載されているウィキペディアの記事も、全てGNU Free Documentation Licenseの元に提供されております。

©2024 GRAS Group, Inc.RSS