Lua Academy · Lektion

Korutinstatus

Kontrollera korutinens tillstånd med coroutine.status: running, suspended, dead.

Lektion 3 av 412 steg

Korutinstatus är en gratis lektion i Lua Academy på CoddyKit. Detta är lektion 3 av 4. Du kan läsa vilka 3 lektioner som helst i den här lärvägen kostnadsfritt i sin helhet – därefter låser CoddyKit PRO upp alla lektioner, plus praktisk övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Den ingår i lärvägen för Lua Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Lua Academy innehåller totalt 4 lektioner.

Fyra coroutine-tillstånd

Coroutines har fyra möjliga tillstånd: suspended (skapad eller yield:ad och väntar på att köras), running (körs just nu), normal (pausad för att låta en annan coroutine köras) och dead (avslutad eller felaktig). Fråga efter tillståndet med coroutine.status(co).

local co = coroutine.create(function()
  print(coroutine.status(coroutine.running()))  -- running
  coroutine.yield()
end)

print(coroutine.status(co))  -- suspended
coroutine.resume(co)          -- prints: running
print(coroutine.status(co))  -- suspended
coroutine.resume(co)
print(coroutine.status(co))  -- dead

Tillståndet "normal"

En coroutine hamnar i tillståndet "normal" när den återupptar en annan coroutine. Den körs inte (det gör den andra coroutinen), men den är inte heller suspended — den väntar på att den återupptagna coroutinen ska yield:a. Detta tillstånd är ovanligt men viktigt att förstå vid komplexa coroutine-grafer.

local inner, outer

inner = coroutine.create(function()
  print("outer status:", coroutine.status(outer))  -- normal
  coroutine.yield()
end)

outer = coroutine.create(function()
  coroutine.resume(inner)
end)

coroutine.resume(outer)
-- prints: outer status: normal

Kontroll före resume

Kontrollera alltid en coroutine-status innan ni återupptar den, särskilt i loopar. Att återuppta en dead coroutine är ett fel. Att återuppta en running coroutine är också ett fel (det skulle orsaka oändlig rekursion).

local function safeResume(co, ...)
  local status = coroutine.status(co)
  if status == "dead" then
    return false, "cannot resume dead coroutine"
  end
  if status == "running" then
    return false, "cannot resume running coroutine"
  end
  return coroutine.resume(co, ...)
end

Status efter fel

När en coroutine-kropp utlöser ett obevakat fel returnerar coroutine.resume false och felmeddelandet. Coroutinen övergår till tillståndet "dead". Den kan inte startas om — ni måste skapa en ny coroutine om ni vill försöka igen.

local co = coroutine.create(function()
  error("something went wrong")
end)

local ok, err = coroutine.resume(co)
print(ok, err)                      -- false  ...: something went wrong
print(coroutine.status(co))         -- dead

-- Cannot resume dead coroutine:
local ok2, err2 = coroutine.resume(co)
print(ok2, err2)  -- false  cannot resume dead coroutine

coroutine.isyieldable

coroutine.isyieldable() returnerar true om den körande coroutinen kan yield:a. Den returnerar false i huvudtråden och i C-funktioner som inte stöder yielding. Kontrollera alltid detta innan ni yield:ar om ni är osäkra på kontexten.

local co = coroutine.create(function()
  print("isyieldable:", coroutine.isyieldable())  -- true
  coroutine.yield()
end)

coroutine.resume(co)

-- In main thread:
print("isyieldable:", coroutine.isyieldable())  -- false
-- coroutine.yield()  -- ERROR in main thread

Övervaka en uppsättning coroutines

Spåra en pool med coroutines och ta bort dead coroutines efter varje omgång av resume-anrop. Detta utgör grunden för en aktivitetsschemaläggare.

local function makeWorker(n, name)
  return coroutine.create(function()
    for i = 1, n do
      print(name, "step", i)
      coroutine.yield()
    end
  end)
end

local workers = {
  makeWorker(2, "fast"),
  makeWorker(4, "slow"),
}

while #workers > 0 do
  local alive = {}
  for _, co in ipairs(workers) do
    coroutine.resume(co)
    if coroutine.status(co) ~= "dead" then
      alive[#alive+1] = co
    end
  end
  workers = alive
end

Felsökning av coroutines

Använd statuskontroller för att instrumentera och felsöka coroutine-baserad kod. Skriv ut statusövergångar för att förstå flödet. I komplexa system kan ni tilldela coroutines namn via en wrapper-tabell för tydligare felsökningsutskrifter.

local function namedCo(name, fn)
  local co = coroutine.create(fn)
  return {
    co = co,
    name = name,
    resume = function(self, ...)
      print("[" .. self.name .. "] resume")
      local results = table.pack(coroutine.resume(self.co, ...))
      print("[" .. self.name .. "] status: " .. coroutine.status(self.co))
      return table.unpack(results, 1, results.n)
    end
  }
end

local worker = namedCo("worker1", function()
  coroutine.yield()
end)
worker:resume()
worker:resume()

Starta om dead coroutines

När en coroutine är dead kan den inte återupptas. För att "starta om" den måste ni skapa en ny coroutine från samma funktion. Ett vanligt mönster är en factory som skapar en ny coroutine vid behov.

local function makeCounter(start, step)
  return coroutine.wrap(function()
    local n = start or 0
    while true do
      coroutine.yield(n)
      n = n + (step or 1)
    end
  end)
end

local count = makeCounter(0, 2)
for i = 1, 5 do io.write(count() .. " ") end
print()  -- 0 2 4 6 8

-- "Restart" by creating a new one
count = makeCounter(100)
print(count())   -- 100

Felhantering i Coroutine.wrap

När en wrapped coroutine får ett fel propagerar felet ut ur wrapper-funktionsanropet. Till skillnad från coroutine.resume, som returnerar false+error, kastar funktioner som returnerats av wrap felet direkt. Använd pcall runt wrap-anrop om ni behöver fånga fel.

local gen = coroutine.wrap(function()
  coroutine.yield(1)
  error("oops")
  coroutine.yield(2)  -- never reached
end)

print(gen())   -- 1 (ok)
local ok, err = pcall(gen)
print(ok, err) -- false  ...: oops
-- Subsequent call: dead coroutine
ok, err = pcall(gen)
print(ok, err) -- false  cannot resume dead coroutine

isyieldable jämfört med status

Det finns två sätt att inspektera coroutine-kontexten: coroutine.status(co) anger tillståndet för en specifik coroutine, medan coroutine.isyieldable() anger om den aktuella exekveringskontexten kan yield:a. Använd status för att kontrollera andra coroutines och isyieldable för att kontrollera om ni säkert kan yield:a.

local function maybeYield()
  if coroutine.isyieldable() then
    coroutine.yield()
  else
    -- in main thread or non-yieldable context
    print("cannot yield here")
  end
end

maybeYield()  -- prints "cannot yield here" (main thread)

local co = coroutine.create(maybeYield)
coroutine.resume(co)   -- yields successfully

Snabb kontroll

Vilket tillstånd övergår en coroutine till när den har kört klart sin kroppsfunktion?

Sammanfattning: Coroutine-status

Sammanfattning:

  • Tillstånd: suspended → running ↔ normal → dead
  • coroutine.status(co) returnerar tillståndssträngen
  • Dead = avslutad eller felaktig; kan inte återupptas
  • coroutine.isyieldable() kontrollerar om den aktuella kontexten kan yield:a
  • Kontrollera alltid status innan ni återupptar i loopar
  • wrap-fel propagerar direkt; resume returnerar false+err
Gratis att börja

Lär dig Lua med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
40
Lektioner
159

Vanliga frågor

Är lektionen ”Korutinstatus” gratis?

Ja – du kan läsa vilka 3 lektioner som helst i lärvägen Lua Academy, inklusive ”Korutinstatus”, kostnadsfritt i sin helhet här på webben. Därefter låser CoddyKit PRO upp alla lektioner, plus interaktiv övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Kursen i Lua Academy innehåller totalt 4 lektioner.

Vad lär jag mig i ”Korutinstatus”?

Kontrollera korutinens tillstånd med coroutine.status: running, suspended, dead. Ni övar på Lua Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig Lua Academy?

Du behöver inga förkunskaper. Utbildningen i Lua Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 3 av 4.

Hur lång tid tar lektionen ”Korutinstatus”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här Lua Academy-lektionen?

Ja. Varje Lua Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. Skapa korutiner
  2. resume och yield
  3. Korutinstatus
  4. Producent-konsument-mönstret
← Tillbaka till Lua Academy