Creazione delle coroutine
Crei coroutine con coroutine.create e coroutine.wrap.
Creazione delle coroutine è una lezione Lua Academy gratuita su CoddyKit. Questa è la lezione 1 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Lua Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Lua Academy include 4 lezioni in totale.
Che cos'è una coroutine?
Una coroutine è una funzione che può sospendere la propria esecuzione (yield) e riprenderla successivamente dal punto in cui si era fermata. A differenza dei thread, le coroutine sono cooperative: ne viene eseguita una sola alla volta e ciascuna cede esplicitamente il controllo. Le coroutine Lua hanno un proprio stack e proprie variabili locali.
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 e coroutine.wrap
coroutine.create(fn) crea una coroutine e restituisce un oggetto coroutine (di tipo thread). coroutine.wrap(fn) crea una coroutine e restituisce una funzione che, quando viene chiamata, la riprende. wrap è più semplice, ma nasconde l'oggetto coroutine.
-- 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)) -- 15Ciclo di vita di una coroutine
Una coroutine può trovarsi in quattro stati: suspended (non in esecuzione), running (in esecuzione), dead (terminata o con errore) e normal (in pausa perché ha ripreso un'altra coroutine). Controlli lo stato con 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)) -- deadEsecuzione di più coroutine
Crei più coroutine e le alterni riprendendole una alla volta. In questo modo simula l'esecuzione concorrente (multitasking cooperativo). Ogni coroutine conserva il proprio stato tra un yield e l'altro.
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:3Iterazione con coroutine.wrap
coroutine.wrap viene comunemente usato per creare iteratori. La funzione restituita viene chiamata ogni volta che l'iteratore avanza. Quando termina il corpo della coroutine, la funzione genera un errore: se necessario, usi pcall o controlli lo stato.
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 5Errore nelle coroutine
Se una coroutine genera un errore, coroutine.resume restituisce false seguito dal messaggio di errore. La coroutine passa allo stato dead. Una coroutine terminata non può essere ripresa.
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 coroutineIdentità della coroutine
coroutine.running() restituisce la coroutine attualmente in esecuzione e un valore booleano che indica se si tratta del thread principale. Usi questa funzione all'interno di una coroutine per ottenere un riferimento a se stessa.
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) -- trueGeneratore infinito
Il corpo di una coroutine può contenere un ciclo infinito con istruzioni yield al suo interno: il generatore produce valori su richiesta senza terminare. Questo è un caso d'uso fondamentale: sequenze infinite e lazy.
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 8Le coroutine come attività
Un semplice scheduler di attività memorizza le coroutine in una coda e riprende ciascuna a turno. Quando una coroutine esegue uno yield, torna nella coda. Quando termina, viene rimossa. Questo è uno scheduler cooperativo minimale.
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()Memoria delle coroutine
Ogni coroutine ha il proprio stack. Gli stack possono diventare molto grandi in presenza di catene di chiamate profonde. In scenari ad alte prestazioni, eviti di creare migliaia di coroutine attive contemporaneamente. Riutilizzi le coroutine quando possibile oppure utilizzi dei pool.
-- 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")Verifica rapida
In quale stato si trova una coroutine subito dopo coroutine.create(fn)?
Riepilogo: creazione delle coroutine
Riepilogo:
coroutine.create(fn)→ oggetto coroutine;wrap(fn)→ funzione riprendibile- Stati: sospesa → in esecuzione → sospesa/terminata
coroutine.resume(co, ...)avvia/riprende la coroutine- Errori durante la ripresa: false + messaggio di errore; la coroutine passa allo stato terminato
- Generatori infiniti tramite
while true do yield() end - Utilizzi per il multitasking cooperativo e le sequenze lazy
Domande Frequenti
La lezione «Creazione delle coroutine» è gratuita?
Sì — il testo completo di «Creazione delle coroutine» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Lua Academy, passa a CoddyKit PRO. Il corso Lua Academy include 4 lezioni in totale.
Cosa imparerò in «Creazione delle coroutine»?
Crei coroutine con coroutine.create e coroutine.wrap. Eserciti Lua Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Lua Academy?
Non è richiesta alcuna esperienza precedente. Lua Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 1 di 4.
Quanto tempo richiede la lezione «Creazione delle coroutine»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Lua Academy?
Sì. Ogni lezione Lua Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Creazione delle coroutine
- resume e yield
- Stato delle coroutine
- Pattern produttore-consumatore