Stato delle coroutine
Verifichi lo stato di una coroutine con coroutine.status: running, suspended, dead.
Stato delle coroutine è una lezione Lua Academy gratuita su CoddyKit. Questa è la lezione 3 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.
I quattro stati delle coroutine
Le coroutine possono trovarsi in quattro stati: sospesa (creata o sospesa con yield, in attesa di essere eseguita), in esecuzione (in esecuzione in quel momento), normale (in pausa per consentire l'esecuzione di un'altra coroutine) e terminata (conclusa o terminata a causa di un errore). Interroghi lo stato con 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)) -- deadLo stato «normale»
Una coroutine entra nello stato «normale» quando riprende un'altra coroutine. Non è in esecuzione, perché lo è l'altra coroutine, ma non è neppure sospesa: attende che la coroutine ripresa esegua yield. Questo stato è raro, ma è importante comprenderlo quando si lavora con grafi di coroutine complessi.
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: normalControllo prima di resume
Controlli sempre lo stato di una coroutine prima di riprenderla, soprattutto nei cicli. Riprendere una coroutine terminata genera un errore. Anche riprendere una coroutine già in esecuzione genera un errore, perché causerebbe una ricorsione infinita.
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, ...)
endStato dopo un errore
Quando il corpo di una coroutine genera un errore non gestito, coroutine.resume restituisce false e il messaggio di errore. La coroutine passa allo stato «terminata». Non può essere riavviata: se desidera riprovare, deve creare una nuova coroutine.
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 coroutinecoroutine.isyieldable
coroutine.isyieldable() restituisce true se la coroutine in esecuzione può eseguire yield. Restituisce false nel thread principale e nelle funzioni C che non supportano la sospensione. Se non è sicuro del contesto, controlli sempre prima di eseguire yield.
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 threadMonitoraggio di un insieme di coroutine
Monitori un pool di coroutine, rimuovendo quelle terminate dopo ogni ciclo di chiamate a resume. Questa è la base di uno scheduler di attività.
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
endDebug delle coroutine
Utilizzi i controlli dello stato per strumentare ed eseguire il debug del codice basato sulle coroutine. Stampi le transizioni di stato per comprendere il flusso. Nei sistemi complessi, assegni nomi alle coroutine tramite una tabella wrapper per ottenere un output di debug più chiaro.
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()Riavvio delle coroutine terminate
Una volta terminata, una coroutine non può essere ripresa. Per «riavviarla», deve creare una nuova coroutine a partire dalla stessa funzione. Un modello comune consiste nell'utilizzare una factory che crei una nuova coroutine quando necessario.
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()) -- 100Comportamento degli errori di coroutine.wrap
Quando una coroutine avvolta genera un errore, l'errore si propaga all'esterno della chiamata alla funzione wrapper. A differenza di coroutine.resume, che restituisce false+errore, le funzioni restituite da wrap generano direttamente l'errore. Utilizzi pcall attorno alle chiamate a wrap se deve intercettare gli errori.
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 coroutineisyieldable e status a confronto
Esistono due modi per esaminare il contesto di una coroutine: coroutine.status(co) restituisce lo stato di una coroutine specifica; coroutine.isyieldable() indica se il contesto di esecuzione corrente può eseguire yield. Utilizzi status per controllare altre coroutine e isyieldable per verificare se è possibile eseguire yield in sicurezza.
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 successfullyVerifica rapida
In quale stato entra una coroutine quando termina l'esecuzione della propria funzione corpo?
Riepilogo: stato delle coroutine
Riepilogo:
- Stati: sospesa → in esecuzione ↔ normale → terminata
coroutine.status(co)restituisce la stringa che indica lo stato- Terminata = conclusa o terminata a causa di un errore; non può essere ripresa
coroutine.isyieldable()verifica se il contesto corrente può eseguire yield- Controlli sempre lo stato prima di riprendere una coroutine nei cicli
- Gli errori di wrap si propagano direttamente; resume restituisce false+err
Domande Frequenti
La lezione «Stato delle coroutine» è gratuita?
Sì — il testo completo di «Stato 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 «Stato delle coroutine»?
Verifichi lo stato di una coroutine con coroutine.status: running, suspended, dead. 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 3 di 4.
Quanto tempo richiede la lezione «Stato 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