0Pricing
Lua Academy · Aula

Criando corrotinas

Crie corrotinas com coroutine.create e coroutine.wrap.

Criando corrotinas é uma aula grátis de Lua Academy no CoddyKit. Esta é a aula 1 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Lua Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Lua Academy inclui 4 aulas no total.

O que é uma coroutine?

Uma coroutine é uma função que pode pausar sua execução (yield) e depois retomá-la do ponto em que parou. Diferentemente das threads, as coroutines são cooperativas — somente uma é executada por vez, e elas cedem o controle explicitamente. As coroutines de Lua têm sua própria pilha e suas próprias variáveis locais.

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 vs coroutine.wrap

coroutine.create(fn) cria uma coroutine e retorna um objeto coroutine (do tipo thread). coroutine.wrap(fn) cria uma coroutine e retorna uma função que, quando chamada, a retoma. wrap é mais simples, mas oculta o 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 uma coroutine

Uma coroutine tem quatro estados: suspended (não está em execução), running (em execução no momento), dead (retornou ou apresentou um erro) e normal (pausada porque retomou outra coroutine). Verifique o estado com 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

Executando várias coroutines

Crie várias coroutines e intercale-as retomando cada uma por vez. Isso simula uma execução concorrente (multitarefa cooperativa). Cada coroutine mantém seu próprio estado entre os yields.

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

Iteração com coroutine.wrap

coroutine.wrap é comumente usado para criar iteradores. A função retornada é chamada cada vez que o iterador avança. Quando o corpo da coroutine termina, a função gera um erro — use pcall ou verifique o estado, se necessário.

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

Erro em coroutines

Se uma coroutine gerar um erro, coroutine.resume retornará false seguido da mensagem de erro. A coroutine passará para o estado dead. Uma coroutine encerrada não pode ser retomada.

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

Identidade da coroutine

coroutine.running() retorna a coroutine em execução no momento e um booleano que indica se ela é a thread principal. Use isso dentro de uma coroutine para obter uma referência a si mesma.

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

Gerador infinito

O corpo de uma coroutine pode conter um loop infinito com yields — o gerador produz valores sob demanda sem terminar. Este é um caso de uso importante: sequências infinitas e de carregamento tardio.

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 tarefas

Um agendador básico de tarefas: armazene coroutines em uma fila e retome cada uma por vez. Quando uma coroutine gera um yield, ela volta para a fila. Quando termina, é removida. Este é um agendador 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()

Memória das corrotinas

Cada corrotina tem sua própria pilha. As pilhas podem crescer bastante em cadeias de chamadas profundas. Em cenários de alto desempenho, evite criar milhares de corrotinas vivas simultaneamente. Reutilize as corrotinas quando possível ou use conjuntos de objetos.

-- 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ção rápida

Em que estado uma corrotina se encontra imediatamente após coroutine.create(fn)?

Recapitulação: criando corrotinas

Resumo:

  • coroutine.create(fn) → objeto de corrotina; wrap(fn) → função que pode ser retomada
  • Estados: suspensa → em execução → suspensa/morta
  • coroutine.resume(co, ...) inicia/retoma
  • Erros durante a retomada: falso + mensagem de erro; corrotina → morta
  • Geradores infinitos por meio de while true do yield() end
  • Use para multitarefa cooperativa e sequências preguiçosas

Perguntas Frequentes

A aula “Criando corrotinas” é grátis?

Sim — o texto completo de “Criando corrotinas” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Lua Academy, atualize para CoddyKit PRO. O curso de Lua Academy inclui 4 aulas no total.

O que vou aprender em “Criando corrotinas”?

Crie corrotinas com coroutine.create e coroutine.wrap. Você pratica Lua Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar Lua Academy?

Nenhuma experiência prévia é necessária. Lua Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 1 de 4.

Quanto tempo leva a aula “Criando corrotinas”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de Lua Academy?

Sim. Cada aula de Lua Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Criando corrotinas
  2. resume e yield
  3. Estado da corrotina
  4. Padrão produtor-consumidor
← Voltar para Lua Academy