(协程)

简介

  协程(coroutine)是Lua语言中的一个核心特性,它是一种轻量级的线程,可以在特定的时刻挂起和恢复执行,使得程序的控制流程可以更加灵活地切换和管理。

  Lua的协程通过coroutine库来实现,通过使用协程,可以将一个复杂的任务分割成多个阶段,并可以在各个阶段之间暂停和恢复执行。协程的概念类似于线程,但是与线程相比,协程更加轻量级,没有操作系统线程的开销和限制。

  使用协程可以很方便地实现一些需要多个步骤、需要等待的任务,例如网络通信、游戏中的动作处理等。协程可以在每个步骤结束后暂停执行,等待下一个步骤的触发或条件满足后再恢复执行。

正文

协程

协同程序。类似同步的线程,也就是有顺序的线程

协程可以手动的运行或挂起。

协程有四种状态

  • 挂起(suspended)
  • 运行(running)
  • 正常(normal)
  • 死亡(dead)

协程创建后的状态是挂起态

coroutine.create协程创建

local co = coroutine.create(function (a,b)
    print(a+b)
end)

print(type(co))
print(coroutine.status(co))
--输出
thread
suspended

coroutine.resume协程运行

local co = coroutine.create(function ()
    for i = 4, 5, 1 do
        print("co",i)
        
    end
    return 1,2
end)

print(coroutine.resume(co))        --运行
--输出
co	4
co	5
true	1	2

coroutine.yield协程暂停

local co = coroutine.create(function ()
    for i = 4, 5, 1 do
        print("co",i)
        coroutine.yield()	--暂停
        print("over")
    end
    return 1,2
end)

print(coroutine.resume(co))        --运行

协程内外数据传递

Co = coroutine.create(function (a)
    print("协程传入参数:",a)
    print("协程中:",coroutine.status(Co))
    local res = coroutine.yield(50)
    print("重启后,收到传入值:",res)
end)

print(coroutine.status(Co)) --未启动,挂起
local res,value = coroutine.resume(Co,1)
print("挂起返回值:",res,value)--启动,挂起
print(coroutine.status(Co))     --未启动,挂起
print("返回重启是否成功:",coroutine.resume(Co,10))   --重启
print(coroutine.status(Co)) --从yield后面继续运行,结束

--输出
suspended
协程传入参数:	1
协程中:	running
挂起返回值:	true	50
suspended
重启后,收到传入值:	10
返回重启是否成功:	true
dead

协程案例—生产者消费者

local function receive (prod)
    local status,value = coroutine.resume(prod)
    return value
end

local function send (x)
    coroutine.yield(x)
end

local function producer ()
    return coroutine.create(function ()
        while true do
            local x = io.read() --产生新值
            send(x)
        end
    end)
end

local 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

local function consumer(prod)
    while true do
        local x = receive(prod)
        io.write(x,"\n")
    end
end

consumer(filter(producer()))
--用法
--运行后,向控制台输入,然后回车,会输出输入的字符
--重复上述过程