参考:Lua中的协同程序 coroutine http.lua
协同程序(Coroutine):
三个状态:suspended(挂起,协同刚创建完成时或者yield之后)、running(运行)、dead(函数走完后的状态,这时候不能再重新resume)。
coroutine.create(arg):根据一个函数创建一个协同程序,参数为一个函数
coroutine.resume(co):使协同从挂起变为运行(1)激活coroutine,也就是让协程函数开始运行;(2)唤醒yield,使挂起的协同接着上次的地方继续运行。该函数可以传入参数
coroutine.status(co):查看协同状态
coroutine.yield():使正在运行的协同挂起,可以传入参数
优点:可以通过resume-yield来交换数据
示例代码一:
消费者驱动的生产者-消费者模型
produceFunc = function() while true do local value = io.read() print("produce: ", value) coroutine.yield(value) -- 返回生产的值给coroutine.resume() end end consumer = function(p) while true do local status, value = coroutine.resume(p); -- 唤醒生产者进行生产,并接受coroutine.yield()的值进行消费 print("consume: ", value) end end -- 消费者驱动的设计,也就是消费者需要产品时找生产者请求,生产者完成生产后提供给消费者 producer = coroutine.create(produceFunc) consumer(producer)
在生产消费环节之间加入一个中间处理的环节(过滤器):
produceFunc = function() while true do local value = io.read() print("produce: ", value) coroutine.yield(value) -- 返回生产的值 end end filteFunc = function(p) while true do local status, value = coroutine.resume(p); value = value *100 -- 放大一百倍 coroutine.yield(value) end end consumer = function(f, p) while true do local status, value = coroutine.resume(f, p); -- 唤醒生产者进行生产 print("consume: ", value) end end -- 消费者驱动的设计,也就是消费者需要产品时找生产者请求,生产者完成生产后提供给消费者 producer = coroutine.create(produceFunc) filter = coroutine.create(filteFunc) consumer(filter, producer)
示例代码二:
生产者驱动的生产者-消费者模型
local co_yield = coroutine.yield local co_create = coroutine.create local co_status = coroutine.status local co_resume = coroutine.resume consumeFunc = function() for i = 1,10 do local value = co_yield() -- 通过coroutine.yield()来接收 coroutine.resume()传递的值 print("consume: ",value) end end produceFunc = function(consumer) for i = 1,10 do local value = io.read() print("produce: ",value) co_resume(consumer, value) -- 唤醒消费者进行消费 end end consumer = co_create(consumeFunc) co_resume(consumer) -- 唤醒消费准备开始消费 produceFunc(consumer)
注意:在启动coroutine的时候,resume的参数是传给主程序的;在唤醒yield的时候,参数是传递给yield的