Lua笔记7 coroutine

1. 使用

co = coroutine.create(function() print("hi") end)  --创建
coroutine.status(co) -- 获取状态, suspended
coroutine.resume(co) -- 运行
coroutine.status(co) -- 获取状态, dead

2.resume是在保护模式下运行的,所以错误信息是通过co的返回值来处理的

co = coroutine.create(function()
for i=1,2 do
print("co", i)
coroutine.yield() -- 挂起程序
end
end)
print(coroutine.status(co)) -- suspended
coroutine.resume(co) -- co 1
print(coroutine.status(co)) -- suspended
coroutine.resume(co) -- co 2
print(coroutine.status(co)) -- suspended
print(coroutine.status(co)) -- dead
print(coroutine.resume(co)) -- false cannot resume dead coroutine

3. resume-yield交换数据

1) 第一次调用resume, 传给resume的参数就是传给co主程序的参数

co = coroutine.create(function(a, b)
print(a, b)
end)
coroutine.resume(co, 1,2) -- true
-- co 输出 1, 2

2) 之后调用resume, yield函数的返回值,是传给co的额外参数

co = coroutine.create(function(a, b)
print("co", coroutine.yield())
end)
coroutine.resume(co)
coroutine.resume(co, 1,2)

3) 协同程序结束后,resume的返回值是协同主程序的返回值, 多值返回

co = coroutine.create(function(a, b)
return a+b
end)
print(coroutine.resume(co, 1,2)) -- true 3

4. 管道

function receive(prod)
local status, value = coroutine.resume(prod)
return value
end
function send(x)
coroutine.yield(x)
end
function producer()
local i = 0
return coroutine.create(function()
while true do
local x = i
i = i + 1
send(x)
end
end)
end
function filter(prod)
return coroutine.create(function()
for line = 1, math.huge do
local x = receive(prod)
x = string.format("%5d %s", line, x)
send(x)
end
end)
end
function consumer(prod)
while true do
local x = receive(prod)
print("received:" .. x)
end
end
consumer(filter(producer()))