参考链接:
https://www.runoob.com/lua/lua-coroutine.html
https://www.jb51.net/article/64691.htm
一.常用方法
1.coroutine.create() 创建协程
2.coroutine.resume() 恢复协程
3.coroutine.yield() 挂起协程
4.coroutine.status() 返回协程的状态
测试:
co = coroutine.create(function () for i = 1, 10 do print(i) coroutine.yield() end end) coroutine.resume(co) coroutine.resume(co) coroutine.resume(co) -- 输出: -- 1 -- 2 -- 3
二.常用状态
1.suspended 挂起状态。创建协程(create)和挂起协程(yield)后,协程会处于挂起状态
2.running 运行状态。恢复协程(resume)后,协程会处于运行状态
3.dead 停止状态。协程运行结束后处于停止状态
测试:
co = coroutine.create(function () print(coroutine.status(co)) print("hi") end) print(coroutine.status(co)) coroutine.resume(co) print(coroutine.status(co)) -- 输出: -- suspended -- running -- hi -- dead
三.resume和yield之间的数据交换
1.调用resume后,将会从协程起始处或挂起处执行。如下,第一次执行resume,会将参数1,2,3直接传递给协程;第二次执行resume,会从挂起处执行,将参数4,5,6传递给yield(见下例子2),此时再次print,打印的是初次传递给协程的参数
co = coroutine.create(function (a, b, c) print("co", a, b, c) coroutine.yield() print("co2", a, b, c) end) coroutine.resume(co, 1, 2, 3) coroutine.resume(co, 4, 5, 6) --输出: -- co 1 2 3 -- co2 1 2 3
2.将上面的例子稍微修改下。可以看到,yield的返回值为resume的参数
co = coroutine.create(function (a, b, c) print("co", a, b, c) print(coroutine.yield()) print("co2", a, b, c) end) coroutine.resume(co, 1, 2, 3) coroutine.resume(co, 4, 5, 6) --输出: -- co 1 2 3 -- 4 5 6 -- co2 1 2 3
3.再次将上面的例子稍微修改下。可以看到,resume的返回值为true和yield的参数,其中true表示执行成功无报错,如果出现报错则返回值为false和报错信息
co = coroutine.create(function (a, b, c) print("co", a, b, c) print(coroutine.yield("haha", 999)) print("co2", a, b, c) end) print(coroutine.resume(co, 1, 2, 3)) print(coroutine.resume(co, 4, 5, 6)) --输出: -- co 1 2 3 -- true haha 999 -- 4 5 6 -- co2 1 2 3 -- true
4.resume的返回值也可以为true和return的值。return和yield的不同在于,yield后协程处于挂起状态(suspended),而return后协程处于停止状态(dead)
co = coroutine.create(function () return 6, 7 end) print(coroutine.resume(co)) print(coroutine.resume(co)) --输出: -- true 6 7 -- false cannot resume dead coroutine
总结:
resume和yield的配合强大之处在于,resume处于主程中,它将外部状态(数据)传入到协同程序内部;而yield则将内部的状态(数据)返回到主程中。