Lua的协程基础

参考: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的  

 

posted @ 2017-11-22 17:33  lixin[at]hitwh  阅读(419)  评论(0编辑  收藏  举报