0Pricing
Lua Academy · Lección

Creación de coroutines

Cree coroutines con coroutine.create y coroutine.wrap.

Creación de coroutines es una lección gratuita de Lua Academy en CoddyKit. Esta es la lección 1 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Lua Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Lua Academy incluye 4 lecciones en total.

¿Qué es una coroutine?

Una coroutine es una función que puede pausar su ejecución (yield) y reanudarla más tarde desde el punto en el que se detuvo. A diferencia de los hilos, las coroutines son cooperativas: solo una se ejecuta a la vez y ceden el control explícitamente. Las coroutines de Lua tienen su propia pila y sus propias variables locales.

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 frente a coroutine.wrap

coroutine.create(fn) crea una coroutine y devuelve un objeto coroutine (de tipo thread). coroutine.wrap(fn) crea una coroutine y devuelve una función que, al llamarse, la reanuda. wrap es más sencillo, pero oculta el objeto 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 de vida de una coroutine

Una coroutine tiene cuatro estados: suspendida (no se está ejecutando), en ejecución (se está ejecutando), muerta (ha terminado o ha producido un error) y normal (está pausada porque ha reanudado otra coroutine). Compruebe el estado 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

Ejecución de varias coroutines

Cree varias coroutines y altérnelas reanudando cada una por turnos. Esto simula una ejecución simultánea (multitarea cooperativa). Cada coroutine conserva su propio estado entre una cesión y la siguiente.

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

Iteración con coroutine.wrap

coroutine.wrap se utiliza habitualmente para crear iteradores. La función devuelta se llama cada vez que el iterador avanza. Cuando termina el cuerpo de la coroutine, la función produce un error; use pcall o compruebe el estado si es necesario.

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

Errores en coroutines

Si una coroutine produce un error, coroutine.resume devuelve false seguido del mensaje de error. La coroutine pasa al estado dead. Una coroutine muerta no se puede reanudar de nuevo.

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

Identidad de una coroutine

coroutine.running() devuelve la coroutine que se está ejecutando actualmente y un booleano que indica si es el hilo principal. Use esto dentro de una coroutine para obtener una referencia a sí misma.

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

Generador infinito

El cuerpo de una coroutine puede contener un bucle infinito con cesiones en su interior: el generador produce valores bajo demanda sin terminar. Este es un caso de uso clave: secuencias infinitas y perezosas.

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 como tareas

Un planificador de tareas básico almacena las coroutines en una cola y reanuda cada una por turnos. Cuando una coroutine cede el control, vuelve a la cola. Cuando termina, se elimina. Este es un planificador cooperativo mínimo.

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 de las corrutinas

Cada corrutina tiene su propia pila. Las pilas pueden crecer mucho cuando hay cadenas de llamadas profundas. En escenarios de alto rendimiento, evite crear miles de corrutinas activas simultáneamente. Reutilice las corrutinas cuando sea posible o use pools.

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

Comprobación rápida

¿En qué estado se encuentra una corrutina inmediatamente después de coroutine.create(fn)?

Resumen: creación de corrutinas

Resumen:

  • coroutine.create(fn) → objeto corrutina; wrap(fn) → función reanudable
  • Estados: suspendida → en ejecución → suspendida/muerta
  • coroutine.resume(co, ...) inicia o reanuda la corrutina
  • Errores durante la reanudación: false + mensaje de error; la corrutina pasa a estar muerta
  • Generadores infinitos mediante while true do yield() end
  • Úselas para multitarea cooperativa y secuencias perezosas

Preguntas frecuentes

¿La lección «Creación de coroutines» es gratis?

Sí — el texto completo de «Creación de coroutines» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Lua Academy, actualiza a CoddyKit PRO. El curso de Lua Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Creación de coroutines»?

Cree coroutines con coroutine.create y coroutine.wrap. Practicas Lua Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Lua Academy?

No se requiere experiencia previa. Lua Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 1 de 4.

¿Cuánto tiempo toma la lección «Creación de coroutines»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Lua Academy?

Sí. Cada lección de Lua Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Creación de coroutines
  2. resume y yield
  3. Estado de las coroutines
  4. Patrón productor-consumidor
← Volver a Lua Academy