next up previous contents
Next: 4.3 KL1 のゴール優先度指定方法 Up: 4.2.1 プログラムの実行とスケジューリング Previous: 過剰生産とその抑制

要求駆動型プログラミングによる解決

次の方針でプログラムを作成する.

  1. 生産者は生産する必要がなくなったら, その旨を消費者に伝え終了する. さもなければ生産者はひとつ整数を消費者に送る.
  2. 消費者は生産終了の旨を受け取ったら終了する. 消費者は整数をひとつ受け取ったら, 消費した旨を生産者に伝える.
  3. 生産者は消費した旨を受け取ったら上述の手順でさらに生産処理を続ける.

プログラム例を以下に示す.

%  request.kl1
:- module main.

main :- true | generator(next,20000,Stream), consumer(Stream).

generator(_,0,Stream)    :- true | Stream = [].
generator(Next,N,Stream) :- N =\= 0, Next=next |
     Stream = [send(N,NextN)|NextStream],
     N1 := N - 1,
     generator(NextN,N1,NextStream).

consumer([]) :- true | true.
consumer([send(N,Next)|Stream]) :- integer(N) |
     Next = next,
     consumer(Stream).

さすがにこのプログラムは

と, メモリ不足にならずに動く.

このプログラムは図 4.3 の通り生産者に対して, 消費者が整数を受け取った後に nextを送る. 生産者は消費者から 送られてきた nextで同期をとりながら次の整数を消費者に送る (最初の 1 回を除く).

実行トレースを見てみよう.

  
図 4.3: 同期付生産者-消費者問題プログラムの実行

残念ながらサスペンドするゴールが増えていることがわかる. 要求駆動型にもそれなりの欠点があり, 前項のような プログラムと併せて時と場合に応じてプログラミングするのが望ましいと 言えよう.

前項のプログラムを要求駆動型にせずに, KL1 の優先度制御記述を利用して 簡単に実現する方法について次節で説明しよう.



next up previous contents
Next: 4.3 KL1 のゴール優先度指定方法 Up: 4.2.1 プログラムの実行とスケジューリング Previous: 過剰生産とその抑制



KLIC