Lua系统学习16-协同程序Coroutine

协同程序Coroutine
协同程序就是指在一个线程中的同步执行,它是在某个线程下的,由一个线程发起调用,然后挂起。在一个线程中同一时刻只能运行一个协同程序。
关于协同程序 深入了解与实现 可以看我的一个视频 协同程序实现精讲

在lua中 我们使用create创建一个新的协同程序,传入参数是一个函数, create会返回一个thread类型的值。
lua中的协同程序 分别 由4中状态 1.挂起 2.运行 3.死亡 4正常。
当创建一个协同程序时候它处于挂起状态,我们可以通过函数status来检查协同程序的状态。
通过resume我们可以重启协同程序。他将由挂起状态改为运行。

在协同程序中 我们使用 yield关键字 将当前正在运行的协同程序挂起,然后下一次执行(不是下一帧),在下一次执行到后 会根据yield具体内容做具体行为。
当恢复了协同程序的执行时,协同程序会从挂起状态变为运行状态,继续执行下面代码直到遇到下一个yield。

Debug:

co=coroutine.create(function(a,b) print(a) coroutine.yield() print(b)  end)
t=coroutine.resume(co,1,5);
print(coroutine.running(t))
print(coroutine.status(co))
coroutine.resume(co);

print(coroutine.status(co))
coroutine.running(co)
coroutine.resume(co);
print(coroutine.status(co))
print(coroutine.running(co))

print("---------------------------------")
co=coroutine.create(function(a,b) return a+1,b-1  end)
print(coroutine.resume(co,1,5))
co=coroutine.create(function(a,b) return a,b  end)
print(coroutine.resume(co))

Output:

1
nil
suspended
5
dead
dead
nil
---------------------------------
true	2	4
true	nil	nil

Resume-yield 之间是相互作用影响的
yield挂起Resume中的代码片段
而Resume又从上一次Yield开始运行或从代码头开始启动。

协程应用示例:
将接收IO的流程使用协程处理
我们需要有读取者、发送者、文本处理者

function sender(v)
coroutine.yield(v)
end

function receiver(_coroutine)
local success,arg=coroutine.resume(_coroutine)
    return arg;
end

function  creator()
    x=counter()
return coroutine.create(function()
    while true do
        sender(x())
    end
end)
end
function counter()
    i=0
    return function() i=i+1; return i;  end
end
function filter(_coroutine)
   return coroutine.create(
            function()
                for iii = 1, math.huge do
                    local arg=receiver(_coroutine)
                    if arg<55555 then
                        arg="i" .. arg
                    else
                        arg=nil
                    end

                    sender(arg)
                end
            end
    )

end

function consumer(_coroutine)
    while true do

       local x=receiver(_coroutine)

        if x==nil then
            break;
        else
            print(x)
        end

    end
    print("break")
end
c=creator()
f=filter(c)
consumer(f)
ii=0
while ii<=55555 do
    ii=ii+1
    print("Main II" .. ii)
end

经过测试好像这样写协程并没有暂停一帧,还堵塞主线程。

明白了,Unity中的协程是Unity封装好的了。 不同于Lua的协程, unity中的协程是由unity内部去调用类似Resume和Yield的功能。关于暂停 是因为在c#中会记录一个枚举数在迭代器列表中,Unity根据枚举数内容去操作暂停多久。然后再迭代迭代器。而lua中yield 只是起到挂起作用,只是将协同程序暂时挂起,重新启动需要手动去显示去调用,当然你也可以在yield的时候返回一个参数 然后去设置挂起后多久重新启动,这只需要写个计时器即可。

协程是一个“非抢先式的多线程” 不用考虑线程抢先导致的同步问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值