Table of Contents

Lua协程


概要

举个例子

-- Lua中的携程
 
local function f(iNumber)
    print('function f start with '..iNumber)
 
    print('yield = '..coroutine.yield(iNumber + 1)) -- 包含yield就不能当作普通的函数进行调用了
 
    print('function f end')
end
 
-- 创建一个协程
-- 创建的时候函数并没有开始执行
local cf = coroutine.create(f)
 
local value = 0
-- 第一次从函数头开始执行,参数对应过去
-- 运行到yield为止,把yield的参数返回回来
-- yield类似于return
-- 注意resume会多一个返回值,第一个返回值是Status,布尔类型
_,value = coroutine.resume(cf, 1) -- resume的返回值是yield的参数
print('r = '..value)
 
-- 第二次执行,从上一次yield的地方开始
-- yield的返回值是本次resume的参数
coroutine.resume(cf, 10)
 
-- 总结:resume和yield的关系像是一个环,头尾相接
 
-- 查看一个协程的状态
print(coroutine.status(cf))
 
-- 关闭一个协程
coroutine.close(cf)
 
-- 另一种创建协程的方式
-- 好像调用的时候更方便
local wf = coroutine.wrap(f)
function f start with 1
r = 2
yield = 10
function f end
dead

消费者&生产者模型

看一下使用多线程实现的「消费者&生产者模型」:多线程
使用协程实现的「消费者&生产者模型」是这样的:(可以对比一下区别)

-- 生产者&消费者模型
-- 生产者从一个位置读取数据
-- 生产者把数据交给消费者
-- 消费者处理数据:把数据放到新位置
 
local kDataSource = {} -- 数据源位置
local kDataTarget = {} -- 数据目标位置
 
-- 初始化一下源数据
for i=1,10 do
    table.insert(kDataSource, i*i)
end
 
-- 打印一个列表
local printList = function(kName, kList)
    print(kName..':')
    for i=1,#kList do print(i..' = '..kList[i]) end
end
 
printList('Source', kDataSource)
 
local Send = function(kData)
    coroutine.yield(kData)
end
 
local Recv = function(kCoroutine)
    local bStatus, iValue = coroutine.resume(kCoroutine)
    if bStatus then return iValue end
end
 
-- 生产者,一直在生产数据
-- 生产者是一个协程
local Producer = function()
    for i=1,#kDataSource do
        local iValue = kDataSource[i] -- 生产出了数据
        Send(iValue)
    end
end
 
local cProducer = coroutine.create(Producer)
 
-- 消费者,一直在读取数据
local Consumer = function()
    while true do -- 一直尝试拿数据
        local iValue = Recv(cProducer)
        if iValue then print('Recv Data = '..iValue) table.insert(kDataTarget, iValue)
        else print('Recv Done!') break end
    end
end
 
-- 消费者启动!直到生产者停止为止
Consumer()
 
printList('Target', kDataTarget)

问题