1. ホーム
  2. スクリプト・コラム
  3. ルア

Luaプログラミングの例(VIII)。生産者・消費者問題

2022-01-06 09:31:30

この問題は古典的なもので、基本的にどの言語もマルチスレッドに関わりますが、Luaがここまで複雑だとは思いませんでした。
  理解するのに時間がかかったので、ロジック図です。

   最初にコンシューマが呼ばれ、コンシューマが値を必要とするときにプロデューサーが呼ばれ、プロデューサーは値を生成し、コンシューマが再び要求するまで停止する。消費者主導で設計されている。
   図がうまく描けていないので、まずは2つのプログラム間で受け渡しされる情報を処理するフィルターであるFilterを隠すことから始めてください。Filterを取り除くと、2つの"スレッド"(実際には2つの共同プログラム)がお互いを呼び出すので、ロジックが明確になります。resumeはyieldから戻って開始し、ネストをサポートして、スタックの一番上にあるyield位置に戻ります。yieldはノンブロッキング"スレッド同期"です。これは、linuxのパイプライン通信にちょっと似ていますね。


 function receive(prod)
 print("receive is called")
 local status,value = coroutine.resume(prod)
 return value
end

function send(x,prod)
 print("send is called")
 return coroutine.yield(x)
end

function producer()
 return coroutine.create(function ()
 print("producer is called")
 while true do
 print("producer run again")
  local x = io.read()
  send(x)
 end
 end)
end

function filter(prod)
 return coroutine.create(function ()
 for line = 1,1000 do
  print("enter fliter ". .line)
  local x = receive(prod)
  print("receive in filter finished")
  x= string.format("%5d %s",line,x)
  send(x,prod)
 end
 end)
end

function consumer(prod)
 print("consumer is called")
 while true do
 print("consumer run again")
 local x = receive(prod)
 print("retrun customer")
 io.write(x,"\n")
 end
end

p = producer()
f=filter(p)
consumer(f)




走行の結果

consumer is called
consumer run again
receive is called
enter fliter 1
receive is called
producer is called
producer run again
fsy
send is called
receive in filter finished
send is called
retrun customer
  1 fsy
consumer run again
receive is called
enter fliter 2
receive is called
producer run again
gaga
send is called
receive in filter finished
send is called
retrun customer
  2 gaga
consumer run again
receive is called
enter fliter 3
receive is called
producer run again
......