Lua 协程到底有什么用?为什么这段代码不像我期望的那样工作? [英] What are Lua coroutines even for? Why doesn't this code work as I expect it?

查看:32
本文介绍了Lua 协程到底有什么用?为什么这段代码不像我期望的那样工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在理解这段代码时遇到了麻烦……我期待类似于线程的东西,在那里我会得到一个带有随机nooo"和yaaaay"的输出,因为它们都是异步打印的,但是相反,我发现主线程似乎在第一次调用 coroutine.resume() 时阻塞,从而阻止下一个启动,直到第一个让步为止.

I'm having trouble understanding this code... I was expecting something similar to threading where I would get an output with random "nooo" and "yaaaay"s interspersed with each other as they both do the printing asynchronously, but rather I discovered that the main thread seems to block on the first calling of coroutine.resume() and thus prevents the next from being started until the first has yielded.

如果这是预期的操作协程,它们有什么用处,我将如何实现我希望的目标?我是否必须为这些协程实现我自己的调度程序才能异步运行?因为这看起来很混乱,我还不如使用函数!

If this is the intended operation coroutines, what are they useful for, and how would I achieve the goal I was hoping for? Would I have to implement my own scheduler for these coroutines to operate asynchronously?, because that seems messy, and I may as well use functions!

co1 = coroutine.create(function ()
        local i = 1
        while i < 200 do
                print("nooo")
                i = i + 1
        end
        coroutine.yield()
end)

co2 = coroutine.create(function ()
        local i = 1
        while i < 200 do
                print("yaaaay")
                i = i + 1
        end
        coroutine.yield()
end)

coroutine.resume(co1)
coroutine.resume(co2)

推荐答案

协程不是线程.

协程就像从来没有主动调度的线程.所以是的,您是正确的,您必须编写自己的调度程序才能让两个协程同时运行.

Coroutines are like threads that are never actively scheduled. So yes you are kinda correct that you would have to write you own scheduler to have both coroutines run simultaneously.

然而,当涉及到协程时,你没有看到更大的图景.查看维基百科的协程使用列表.这是一个具体的例子,可以指导您朝着正确的方向前进.

However you are missing the bigger picture when it comes to coroutines. Check out wikipedia's list of coroutine uses. Here is one concrete example that might guide you in the right direction.

    -- level script
    -- a volcano erupts every 2 minutes
    function level_with_volcano( interface )
    
        while true do
            wait(seconds(5))
            start_eruption_volcano()
            wait(frames(10))
            s = play("rumble_sound")
            wait( end_of(s) )
            start_camera_shake()
       
            -- more stuff

            wait(minutes(2))
        end
    
    end

上面的脚本可以编写为使用 switch 语句和一些巧妙的状态变量迭代运行.但是当写成协程时就更清楚了.上面的脚本可能是一个线程,但您真的需要将内核线程专用于这个简单的代码.一个繁忙的游戏关卡可能会运行 100 个这样的协程,而不会影响性能.但是,如果这些都是一个线程,您可能在性能开始受到影响之前以 20-30 的速度逃脱.

The above script could be written to run iteratively with a switch statement and some clever state variables. But it is much more clear when written as a coroutine. The above script could be a thread but do you really need to dedicate a kernel thread to this simple code. A busy game level could have 100's of these coroutines running without impacting performance. However if each of these were a thread you might get away with 20-30 before performance started to suffer.

协程旨在允许我编写代码将状态存储在堆栈上,以便我可以停止运行它一段时间(wait 函数)并从我停止的地方重新启动它.

A coroutine is meant to allow me to write code that stores state on the stack so that I can stop running it for a while (the wait functions) and start it again where I left off.

这篇关于Lua 协程到底有什么用?为什么这段代码不像我期望的那样工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆