You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Minecraft ComputerCraft中尝试同时运行两个循环的问题

解决Minecraft ComputerCraft中协程循环无执行动作的问题

嘿,我完全懂你碰到的这个糟心问题——用coroutine.wrap启动两个带循环的函数,开头的打印语句明明能正常输出,可循环体里的代码却像“死”了一样完全没动静。结合ComputerCraft的Lua协程特性,我来帮你拆解问题、给出可行的解决方案。

核心原因分析

在Lua(包括ComputerCraft的运行环境)里,协程是协作式调度的——简单说就是,一个协程必须主动调用coroutine.yield()让出执行权,其他协程才有机会运行。如果你的循环里没加这个操作,大概率会出现两种情况:

  1. 要是你按顺序写coroutine.wrap(constantWork)()coroutine.wrap(lookForKeys)(),第一个协程会直接霸占整个线程,要是是死循环的话就会卡到天荒地老,第二个协程根本没机会启动。不过你说两个开头的print都能打印,说明你可能用了coroutine.create+coroutine.resume的方式同时启动了两个协程,但其中一个协程进循环后一直占着CPU,另一个的循环根本轮不到执行。
  2. 还有一种小概率可能:你的循环条件本身一开始就不满足,导致循环体压根没被触发。不过你明确说循环从170行开始,这种情况可以先排查,但优先级不如第一个原因高。

具体解决方案

1. 给循环体加上协程让出操作

这是最关键的一步,让每个协程在循环的每次迭代中主动“暂停”一下,给其他协程腾运行空间。比如修改你的函数循环:

function constantWork()
    print("Starting constant work routine") -- 你的开头打印
    while true do
        -- 这里放你原本的循环体代码
        -- 每次循环后主动让出执行权
        coroutine.yield()
    end
end

function lookForKeys()
    print("Starting key lookup routine") -- 你的开头打印
    while true do
        -- 这里放你原本的循环体代码
        -- 每次循环后主动让出执行权
        coroutine.yield()
    end
end

2. 用正确的方式调度协程

别再用coroutine.wrap直接调用了(这会同步执行协程直到yield或结束),换成coroutine.create创建协程对象,然后在主循环里交替唤醒两个协程:

-- 创建两个协程对象
local co_constant = coroutine.create(constantWork)
local co_keys = coroutine.create(lookForKeys)

-- 先启动一次两个协程,执行到第一个yield的位置
coroutine.resume(co_constant)
coroutine.resume(co_keys)

-- 主循环:持续交替调度两个协程
while true do
    -- 先检查协程是否还存活,避免报错
    if coroutine.status(co_constant) ~= "dead" then
        coroutine.resume(co_constant)
    end
    if coroutine.status(co_keys) ~= "dead" then
        coroutine.resume(co_keys)
    end
    -- 可选:加个短暂延迟,避免占用过多系统资源
    os.sleep(0.1)
end

3. 排查循环条件的有效性

如果上面的修改后还是没效果,去检查第170行的循环判断条件,确保它能在运行过程中为true。比如如果你的循环是while hasPendingWork do,要确保hasPendingWork变量会在协程运行时被设置为true,不然循环体根本不会执行。

额外小提醒

ComputerCraft的终端是单线程的,所有协程都在这一个线程里跑,所以协作式调度是必须的——没有主动yield,协程会一直独占线程,其他逻辑完全没法动。要是你的循环体是扫描方块、复杂计算这类耗时操作,还可以把操作拆成小块,每完成一小块就yield一次,避免其他协程等太久。

内容的提问来源于stack exchange,提问作者Epuuc

火山引擎 最新活动