• 分类

  • 重置

Lua编程示例(八):生产者-消费者问题

    这个问题是比较经典的啦,基本所有语言的多线程都会涉及到,但是没想到Lua的这个这么复杂 抓狂
      看了好长时间才算看明白,先上个逻辑图:

       开始时调用消费者,当消费者需要值时,再调用生产者生产值,生产者生产值后停止,直到消费者再次请求。设计为消费者驱动的设计。
       图画的不太好,可以先将Filter遮住,它是过滤器对两个程序之间传递的信息进行处理。去掉Filter逻辑就更清晰些了,就是两个“线程”(其实是两个协同程序)互相调用。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
    ......