Lua 协同程序coroutine

前言

Lua协同程序: 开启另一个逻辑处理和c#一样,同一时间只能有一个协同程序被执行
线程:同一时间,可以有多个线程执行
进程:线程的一个载体,一个程序的运行独立为一个进程,进程和进程之间都有自己独立的储存单元、一个进程可以包含多个线程、多个线程之间共享存储单元。
比如打开一个手机游戏,这个游戏就有一个进程,游戏内部有很多线程同时运行,线程都有一个共享单元来获取存储数据

Lua中协同程序的所有函数都被放进一个叫coroutine的表(table)中
Lua中协同程序的4种状态: 运行、挂起、死亡、正常

一、coroutine.create 创建协同程序

创建协同程序,create函数参数位数一个函数
该参数就是协同程序的工作函数,参数函数一般为匿名函数
create函数有一个返回值->协同程序

local  c1 = coroutine.create(function()
    print("我是协同程序")
end)

二、coroutine.status查看状态

协同程序创建后默认为suspended挂起状态,协同程序执行完变成dead死亡状态

local  c1 = coroutine.create(function()
    print("我是协同程序")
end)
print(coroutine.status(c1)) --suspended 挂起

三、coroutine.resume 执行协同程序(开始协同程序)

local  c1 = coroutine.create(function()
    print("我是协同程序")
end)
print(coroutine.status(c1)) --suspended 挂起
coroutine.resume(c1) --执行协同程序(开始协同程序)
print(coroutine.status(c1)) -- dead 死亡结束

四、yield() 挂起

yield 和 c#差不多,停止协同程序,条件满足继续向下执行

local c2 = coroutine.create(function()
    for i = 1 ,2 do
        print(i)
        coroutine.yield() -- 挂起,等待唤醒
        print("go on") -- 被挂起 go on 不再执行
    end
end)
coroutine.resume(c2)
print("LS")  -- 挂起后调用
print(coroutine.status(c2)) -- 挂起状态
coroutine.resume(c2) --唤醒协程继续向下执行,又被挂起了
print(coroutine.status(c2)) -- 挂起状态
coroutine.resume(c2) --再次唤醒直接结束了(循环完了2次)
print(coroutine.status(c2)) -- dead结束状态

五、resume: 方法有两个返回值

1.协同程序是否正确执行(正确true,错误false)
2. 错误原因(正确返回nill, 错误返回string)

local c3 = coroutine.create(function()
    print("协同程序")
    error("协同程序发生错误")--强制报错,报错原因是:协同程序发生错误
end
)
local result ,err = coroutine.resume(c3)
print(result)
print(err) -- 协同程序不会报错,而是在这里把错误原因打印出来

六、resume: 协同程序函数带有参数

local c4 = coroutine.create(function(name,age)
    print(name)
    print(age)
end
)
coroutine.resume(c4,"Young",333) -- 在调用协同程序后面按顺序依次添加

七、resume: 函数第二个返回值

如果协同程序发生错误,第二个返回值为错误信息
如果协同程序没有发生错误,那么
第二个返回值为yield函数的参数

local c5 = coroutine.create(function()
    print("lua")
    --error("抛出异常") --测试错误情况
    coroutine.yield("挂起协同程序") --此处不会打印
end)

local result, err = coroutine.resume(c5)
print(result)
print(err) -- 打印返回yield的参数:挂起协同程序

八、yield函数返回值就是rusume函数的第二个参数

上面的例子可以说是:yield 函数的参数是resume函数的第二个返回值
而现在这个例子说的是:yield 函数的返回值是resume函数的第二个参数
有点复杂,可以根据例子来理解

local c6 = coroutine.create(function(name)
    local b = coroutine.yield("返回给rusume函数")
    print(b)--打印A
end)
coroutine.resume(c6,"Y") --第一次"Y"是给协同程序的形参name作实参传入,但是协同程序被yield挂起了
coroutine.resume(c6,"A") --第二次继续执行协同程序,此时第二个参数”A“就是yiled函数的返回值

九、协同程序中函数带有返回值

协同程序中函数的第一个返回值给了resume函数的第二个返回值上
下次继续执行协同程序,resume函数返回值依次为
true
nil
abc
hello lua

local c7 = coroutine.create(function()
    coroutine.yield("挂起协同程序")
    return nil, "abc", "hello lua"
end)

local result ,err = coroutine.resume(c7)
print(result) -- true
print(err) -- 挂起协同程序
local result , err, ret1, ret2 = coroutine.resume(c7)
print(result) -- true
print(err)  -- nil
print(ret1) --abc 
print(ret2) --hello lua

官方文档案例

再读读官方文档的例子,加深理解
yield 函数的参数是resume函数的第二个返回值,(第一个返回值是true)
resume函数的第二个参数是yield 函数的返回值,(第一个参数是协同程序变量(函数)名)

function foo (a)
    print("foo", a)
    return coroutine.yield(2*a)
end

co = coroutine.create(function (a,b)
      print("co-body", a, b) 
      local r = foo(a+1) 
      print("co-body", r)
      local r, s = coroutine.yield(a+b, a-b)
      print("co-body", r, s)
      return b, "end"
end)

print("main", coroutine.resume(co, 1, 10))
print("main", coroutine.resume(co, "r"))
print("main", coroutine.resume(co, "x", "y"))
print("main", coroutine.resume(co, "x", "y"))

打印结果:
When you run it, it produces the following output:

扫描二维码关注公众号,回复: 2577412 查看本文章
 co-body 1       10
 foo     2
 main    true    4
 co-body r
 main    true    11      -9
 co-body x       y
 main    true    10      end
 main    false   cannot resume dead coroutine

猜你喜欢

转载自blog.csdn.net/liaoshengg/article/details/81333521
今日推荐