0Pricing
Lua Academy · Aula

Estado da corrotina

Verifique o estado da corrotina com coroutine.status: running, suspended, dead.

Estado da corrotina é uma aula grátis de Lua Academy no CoddyKit. Esta é a aula 3 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.

Quatro estados de uma corrotina

As corrotinas têm quatro estados possíveis: suspensa (criada ou após yield, aguardando execução), em execução (sendo executada no momento), normal (pausada para permitir que outra corrotina seja executada) e morta (finalizada ou com erro). Consulte com 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))  -- dead

O estado “normal”

Uma corrotina entra no estado “normal” quando retoma outra corrotina. Ela não está em execução (a outra está), mas também não está suspensa — está aguardando a corrotina retomada produzir um yield. Esse estado é raro, mas é importante compreendê-lo em grafos complexos de corrotinas.

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: normal

Verificação antes da retomada

Sempre verifique o status de uma corrotina antes de retomá-la, especialmente em laços. Retomar uma corrotina morta é um erro. Retomar uma corrotina em execução também é um erro (causaria recursão 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, ...)
end

status após um erro

Quando o corpo de uma corrotina gera um erro não capturado, coroutine.resume retorna falso e a mensagem de erro. A corrotina passa ao estado “morta”. Ela não pode ser reiniciada — você precisa criar uma nova corrotina se quiser tentar novamente.

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 coroutine

coroutine.isyieldable

coroutine.isyieldable() retorna true se a corrotina em execução puder produzir yield. Retorna false na thread principal e em funções C que não oferecem suporte a yield. Sempre verifique antes de produzir yield se não tiver certeza sobre o contexto.

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 thread

Monitorando um conjunto de corrotinas

Acompanhe um conjunto de corrotinas, removendo as mortas após cada rodada de retomadas. Essa é a base de um agendador de tarefas.

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
end

Depuração de corrotinas

Use verificações de status para instrumentar e depurar código baseado em corrotinas. Exiba as transições de status para entender o fluxo. Em sistemas complexos, atribua nomes às corrotinas por meio de uma tabela de encapsulamento para obter uma saída de depuração mais clara.

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

Reiniciando corrotinas mortas

Quando uma corrotina está morta, não é possível retomá-la. Para “reiniciá-la”, você precisa criar uma nova corrotina a partir da mesma função. Um padrão comum é usar uma fábrica que crie uma corrotina nova sob demanda.

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())   -- 100

Comportamento de erro de Coroutine.wrap

Quando uma corrotina encapsulada gera um erro, o erro se propaga para fora da chamada da função de encapsulamento. Diferentemente de coroutine.resume, que retorna falso+erro, as funções retornadas por wrap geram o erro diretamente. Use pcall ao redor das chamadas de wrap se precisar capturar erros.

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 coroutine

isyieldable versus status

Há duas maneiras de inspecionar o contexto da corrotina: coroutine.status(co) informa o estado de uma corrotina específica; coroutine.isyieldable() informa se o contexto de execução atual pode produzir yield. Use status para verificar outras corrotinas; use isyieldable para verificar se é seguro produzir yield.

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 successfully

Verificação rápida

Em que estado uma corrotina entra quando termina de executar sua função de corpo?

Recapitulação: status da corrotina

Resumo:

  • Estados: suspensa → em execução ↔ normal → morta
  • coroutine.status(co) retorna a cadeia de caracteres do estado
  • Morta = finalizada ou com erro; não pode ser retomada
  • coroutine.isyieldable() verifica se o contexto atual pode produzir yield
  • Sempre verifique o status antes de retomar em laços
  • Erros de wrap propagam-se diretamente; resume retorna falso+err

Perguntas Frequentes

A aula “Estado da corrotina” é grátis?

Sim — o texto completo de “Estado da corrotina” é 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 “Estado da corrotina”?

Verifique o estado da corrotina com coroutine.status: running, suspended, dead. 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 3 de 4.

Quanto tempo leva a aula “Estado da corrotina”?

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