Lua Academy · Lektion

Skapa korutiner

Skapa korutiner med coroutine.create och coroutine.wrap.

Lektion 1 av 412 steg

Skapa korutiner är en gratis lektion i Lua Academy på CoddyKit. Detta är lektion 1 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.

Vad är en coroutine?

En coroutine är en funktion som kan pausa sin körning (yield) och senare fortsätta där den slutade. Till skillnad från trådar är coroutines samarbetsstyrda – endast en körs åt gången och de lämnar uttryckligen över kontrollen. Lua-coroutines har en egen stack och egna lokala variabler.

local co = coroutine.create(function()
  print("start")
  coroutine.yield()
  print("resumed")
  coroutine.yield()
  print("done")
end)

print(coroutine.status(co))   -- suspended
coroutine.resume(co)          -- start
print(coroutine.status(co))   -- suspended
coroutine.resume(co)          -- resumed

coroutine.create jämfört med coroutine.wrap

coroutine.create(fn) skapar en coroutine och returnerar ett coroutine-objekt (av typen thread). coroutine.wrap(fn) skapar en coroutine och returnerar en funktion som återupptar den när den anropas. wrap är enklare men döljer coroutine-objektet.

-- create: returns coroutine object
local co = coroutine.create(function(x)
  return x * 2
end)
local ok, val = coroutine.resume(co, 5)
print(ok, val)   -- true  10

-- wrap: returns a resumable function
local gen = coroutine.wrap(function(x)
  return x * 3
end)
print(gen(5))    -- 15

Coroutinens livscykel

En coroutine har fyra tillstånd: suspended (körs inte), running (körs just nu), dead (har returnerat eller orsakat ett fel) och normal (pausad eftersom den återupptog en annan coroutine). Kontrollera tillståndet med coroutine.status(co).

local co = coroutine.create(function()
  coroutine.yield()
end)

print(coroutine.status(co))  -- suspended
coroutine.resume(co)          -- runs until yield
print(coroutine.status(co))  -- suspended again
coroutine.resume(co)          -- runs until end
print(coroutine.status(co))  -- dead

Köra flera coroutines

Skapa flera coroutines och varva mellan dem genom att återuppta var och en i tur och ordning. Detta simulerar samtidig körning (samarbetsstyrd multitasking). Varje coroutine behåller sitt eget tillstånd mellan sina yield-anrop.

local function worker(name, steps)
  for i = 1, steps do
    print(name .. ": step " .. i)
    coroutine.yield()
  end
end

local co1 = coroutine.create(function() worker("A", 3) end)
local co2 = coroutine.create(function() worker("B", 3) end)

for _ = 1, 3 do
  coroutine.resume(co1)
  coroutine.resume(co2)
end
-- A:1, B:1, A:2, B:2, A:3, B:3

Iteration med coroutine.wrap

coroutine.wrap används ofta för att skapa iteratorer. Den returnerade funktionen anropas varje gång iteratorn går vidare. När coroutine-kroppen avslutas orsakar funktionen ett fel – använd pcall eller kontrollera tillståndet vid behov.

local function range(n)
  return coroutine.wrap(function()
    for i = 1, n do
      coroutine.yield(i)
    end
  end)
end

for v in range(5) do
  io.write(v .. " ")
end
print()  -- 1 2 3 4 5

Fel i coroutines

Om en coroutine orsakar ett fel returnerar coroutine.resume false följt av felmeddelandet. Coroutinen övergår till tillståndet dead. En död coroutine kan inte återupptas.

local co = coroutine.create(function(x)
  if x < 0 then error("negative input: " .. x) end
  return math.sqrt(x)
end)

local ok, val = coroutine.resume(co, -1)
print(ok, val)    -- false  input:2: negative input: -1
print(coroutine.status(co))  -- dead

-- Can't resume a dead coroutine:
ok, val = coroutine.resume(co)
print(ok, val)    -- false  cannot resume dead coroutine

Coroutinens identitet

coroutine.running() returnerar den coroutine som körs för närvarande samt en boolean som anger om den är huvudtråden. Använd detta inuti en coroutine för att få en referens till den själv.

local co = coroutine.create(function()
  local self, isMain = coroutine.running()
  print("type:", type(self))      -- thread
  print("isMain:", isMain)        -- false
  print("status:", coroutine.status(self)) -- running
end)

coroutine.resume(co)

-- In main thread:
local main, isMain = coroutine.running()
print("main isMain:", isMain)    -- true

Oändlig generator

En coroutine-kropp kan innehålla en oändlig loop med yield-anrop inuti – generatorn producerar värden vid behov utan att avslutas. Detta är ett viktigt användningsområde: lata, oändliga sekvenser.

local function naturals(start)
  return coroutine.wrap(function()
    local n = start or 1
    while true do
      coroutine.yield(n)
      n = n + 1
    end
  end)
end

local gen = naturals(1)
for i = 1, 8 do
  io.write(gen() .. " ")
end
print()  -- 1 2 3 4 5 6 7 8

Coroutines som uppgifter

En enkel uppgiftsschemaläggare lagrar coroutines i en kö och återupptar dem i tur och ordning. När en coroutine pausar med yield läggs den tillbaka i kön. När den avslutas tas den bort. Detta är en minimal samarbetsstyrd schemaläggare.

local tasks = {}

local function spawn(fn)
  tasks[#tasks+1] = coroutine.create(fn)
end

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

spawn(function() for i=1,3 do print("T1:"..i); coroutine.yield() end end)
spawn(function() for i=1,3 do print("T2:"..i); coroutine.yield() end end)
run()

Coroutineminne

Varje coroutine har en egen stack. Stackar kan växa sig stora vid djupa anropskedjor. Undvik att skapa tusentals samtidigt aktiva coroutines i högpresterande scenarier. Återanvänd coroutines när det är möjligt, eller använd pooler.

-- Coroutine pool concept
local pool = {}

local function getCoroutine(fn)
  -- Reuse dead coroutine slots
  for i, co in ipairs(pool) do
    if coroutine.status(co) == "dead" then
      pool[i] = coroutine.create(fn)
      return pool[i]
    end
  end
  local co = coroutine.create(fn)
  pool[#pool+1] = co
  return co
end

print("Pool pattern for coroutine reuse")

Snabb kontroll

Vilket tillstånd befinner sig en coroutine i direkt efter coroutine.create(fn)?

Sammanfattning: Skapa coroutines

Sammanfattning:

  • coroutine.create(fn) → coroutine-objekt; wrap(fn) → återupptagningsbar funktion
  • Tillstånd: suspended → running → suspended/dead
  • coroutine.resume(co, ...) startar/återupptar
  • Fel under resume: false + felmeddelande; coroutine → dead
  • Oändliga generatorer via while true do yield() end
  • Använd för kooperativ multitasking och lata sekvenser
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 ”Skapa korutiner” gratis?

Ja – du kan läsa vilka 3 lektioner som helst i lärvägen Lua Academy, inklusive ”Skapa korutiner”, 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 ”Skapa korutiner”?

Skapa korutiner med coroutine.create och coroutine.wrap. 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 1 av 4.

Hur lång tid tar lektionen ”Skapa korutiner”?

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