Oprettelse af coroutiner
Opret coroutiner med coroutine.create og coroutine.wrap.
Oprettelse af coroutiner er en gratis Lua Academy-lektion på CoddyKit. Dette er lektion 1 af 4. Du kan læse alle 3 lektioner i dette læringsspor gratis i deres fulde længde — derefter låser CoddyKit PRO alle lektioner op samt praktiske øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Den er en del af læringsforløbet i Lua Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Lua Academy-kurset indeholder 4 lektioner i alt.
Hvad er en coroutine?
En coroutine er en funktion, der kan sætte sin udførelse på pause (yield) og senere fortsætte fra det sted, hvor den slap. I modsætning til tråde er coroutiner samarbejdende – kun én kører ad gangen, og de afgiver eksplicit kontrollen. Lua-coroutiner har deres egen stack og lokale 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) -- resumedcoroutine.create kontra coroutine.wrap
coroutine.create(fn) opretter en coroutine og returnerer et coroutine-objekt (typen thread). coroutine.wrap(fn) opretter en coroutine og returnerer en funktion, der genoptager den, når den kaldes. wrap er enklere, men skjuler 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)) -- 15Coroutine-livscyklus
En coroutine har fire tilstande: suspenderet (kører ikke), kører (udføres i øjeblikket), død (returneret eller med en fejl) og normal (sat på pause, fordi den genoptog en anden coroutine). Kontrollér tilstanden 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)) -- deadKørsel af flere coroutiner
Opret flere coroutiner, og flet deres kørsel ved at genoptage dem på skift. Det simulerer samtidig udførelse (samarbejdende multitasking). Hver coroutine bevarer sin egen tilstand mellem yield-kald.
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:3Iteration med coroutine.wrap
coroutine.wrap bruges ofte til at oprette iteratorer. Den returnerede funktion kaldes, hver gang iteratoren går videre. Når coroutine-kroppen afsluttes, udløser funktionen en fejl – brug pcall, eller kontrollér tilstanden, hvis det er nødvendigt.
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 5Fejl i coroutiner
Hvis en coroutine udløser en fejl, returnerer coroutine.resume false efterfulgt af fejlmeddelelsen. Coroutinen skifter til tilstanden dead. En død coroutine kan ikke genoptages igen.
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 coroutineCoroutine-identitet
coroutine.running() returnerer den coroutine, der kører i øjeblikket, samt en boolesk værdi, der angiver, om den er hovedtråden. Brug dette inde i en coroutine for at få en reference til den selv.
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) -- trueUendelig generator
En coroutine-krop kan indeholde en uendelig løkke med yield-kald – generatoren producerer værdier efter behov uden at afslutte. Dette er et vigtigt anvendelsesområde: dovne, uendelige 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 8Coroutiner som opgaver
En grundlæggende opgaveplanlægger: gem coroutiner i en kø, og genoptag dem på skift. Når en coroutine udfører yield, sættes den tilbage i køen. Når den dør, fjernes den. Dette er en minimal samarbejdende planlægger.
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()Coroutinehukommelse
Hver coroutine har sin egen stak. Stakke kan blive store ved dybe kaldkæder. I scenarier med høje ydeevnekrav bør du undgå at oprette tusindvis af coroutiner, der er aktive samtidig. Genbrug coroutiner, når det er muligt, eller brug puljer.
-- 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")Hurtigt tjek
Hvilken tilstand er en coroutine i umiddelbart efter coroutine.create(fn)?
Opsummering: Oprettelse af coroutiner
Opsummering:
coroutine.create(fn)→ coroutine-objekt;wrap(fn)→ funktion, der kan genoptages- Tilstande: suspenderet → kører → suspenderet/død
coroutine.resume(co, ...)starter eller genoptager- Fejl under genoptagelse: false + fejlmeddelelse; coroutine → død
- Uendelige generatorer via
while true do yield() end - Bruges til kooperativ multitasking og dovne sekvenser
Lær Lua med en AI-underviser — gratis
Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.
- Kurser
- 40
- Lektioner
- 159
Ofte stillede spørgsmål
Er lektionen “Oprettelse af coroutiner” gratis?
Ja — alle 3 lektioner i læringssporet Lua Academy, inklusive “Oprettelse af coroutiner”, kan læses gratis i deres fulde længde her på webstedet. Derefter låser CoddyKit PRO alle lektioner op samt interaktive øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Lua Academy-kurset indeholder 4 lektioner i alt.
Hvad lærer jeg i “Oprettelse af coroutiner”?
Opret coroutiner med coroutine.create og coroutine.wrap. Du øver dig i Lua Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.
Skal jeg have erfaring for at begynde på Lua Academy?
Der kræves ingen tidligere erfaring. Lua Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 1 af 4.
Hvor lang tid tager lektionen “Oprettelse af coroutiner”?
De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.
Kan jeg skrive og køre kode i denne Lua Academy-lektion?
Ja. Alle Lua Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.
Alle lektioner i dette kursus
- Oprettelse af coroutiner
- resume og yield
- Coroutine-status
- Producer-forbruger-mønster