[Lua]协程

参考链接:

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则将内部的状态(数据)返回到主程中。

原文地址:https://www.cnblogs.com/lyh916/p/12209569.html