0Pricing
Lua Academy · Lezione

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)          -- resumed

coroutine.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))    -- 15

Ciclo 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))  -- dead

Esecuzione 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:3

Iterazione 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 5

Errore 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 coroutine

Identità 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)    -- true

Generatore 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 8

Le 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

  1. Creazione delle coroutine
  2. resume e yield
  3. Stato delle coroutine
  4. Pattern produttore-consumatore
← Torna a Lua Academy