[]Lua协同程序(coroutine)
-
特点:
-
拥有独立的堆栈、独立的局部变量和独立的指令指针。
-
与其他协同程序共享全局变量和其他大部分东西。
-
-
线程和协同程序的区别:
-
具有多个线程的程序,多个线程可以同时运行;但是具有多个协程的程序,同一时刻只能有一个协程运行。
-
-
基本语法:
-
coroutine.create()
-
功能:创建coroutine;
-
参数:一个函数,coroutine运行时,实际运行的是该函数。与coroutine.resume()配合使用。
-
返回值:coroutine;
-
-
coroutine.resume()
-
功能:重新运行指定的coroutine;
-
参数:
-
coroutine:指定需要重新运行的coroutine;
-
其他参数:根据功能需要,可传入任意值,该参数列表会作为yield()的返回值。
-
-
返回值:
-
true/false:本次resume操作的结果。当协程执行完成后,再次resume,会返回false;
-
其他参数:coroutine.yield()的参数列表。
-
-
-
coroutine.yield()
-
功能:挂起当前运行的coroutine,将当前coroutine设置为suspend状态;
-
参数:根据功能需要,可传入任意值,该参数列表会作为resume()的返回值。
-
返回值:coroutine.resume()的参数列表。
-
-
coroutine.status():
-
功能:查看指定coroutine的运行状态。
-
参数:coroutine。
-
返回值(coroutine的运行状态):
-
suspended: 挂起状态。通过coroutine.create()刚创建的coroutine处于该状态。
-
running: 运行状态。
-
dead: coroutine的函数运行结束后,coroutine处于该状态。
-
-
-
coroutine.running():
-
coroutine.wrap()
-
功能:创建coroutine;
-
参数:一个函数;
-
返回值:一个函数。调用该函数时,该coroutine就运行了。
-
-
-
示例1:关于协程的三种状态。
-
function funcTest()
-
print(coroutine.status(co)) --该协程通过resume唤醒后,处于running状态。
-
-
end
-
co = coroutine.create(funcTest) --创建coroutine。
-
coroutine.status(co) --新创建的coroutine处于suspended状态。
-
coroutine.resume(co) --唤醒指定协程。
-
coroutine.status(co) --协程函数运行完成,此时coroutine处于dead状态。
-
-
示例2:关于yield和resume的参数和返回值。
-
function funcTest()
-
res1, res2, res3 = coroutine.yield('y11', 'y22', 'y33')
-
print(res1, res2, res3) --依次输出:'r11', 'r22', 'r33'
-
return
-
-
end
-
co = coroutine.create(funcTest) --创建协程
-
status, y1, y2, y3 = coroutine.resume(co, 'r1', 'r2', 'r3') --唤醒协程;本次resume调用的参数('r1', 'r2', 'r3')无用!
-
print(status, y1, y2, y3) --依次输出:true, 'y11', 'y22', 'y33',也就是yield的参数列表。
-
status, y1, y2, y3 = coroutine.resume(co, 'r11', 'r22', 'r33') --
-
print(status, y1, y2, y3)--依次输出:true, nil, nil, nil
-
总结:
-
resume一般运行在主程中,通过resume的参数列表将外部状态传入到协同程序内部;
-
yeild一般运行在协程内,通过yield的参数列表将协程内部的状态传入到主程中。
-
-
-
示例3:生产者与消费者。
-
local coProdutor
-
function funcProdutor()
-
for i = 1, 10 do
-
coroutine.yield(i) --生产者运行在协程内,每次向主程返回i的值。
-
-
end
-
-
end
-
function funcConsumer()
-
while true do
-
status, value = coroutine.resume(coProdutor) --消费者运行在主程内,唤醒生产者生产数据后,进行打印处理。
-
print("[con]", "status:", status, "value:", value)
-
if false == status then --如果生产者不再生产数据,消费者退出。
-
break
-
-
end
-
-
end
-
-
end
-
coProdutor = coroutine.create(funcProdutor) --创建生产者协程
-
funcConsumer() --启动消费者
-