0Pricing
Lua Academy · Leçon

État d’une coroutine

Vérifiez l’état d’une coroutine avec coroutine.status : running, suspended, dead.

État d’une coroutine est une leçon Lua Academy gratuite sur CoddyKit. Ceci est la leçon 3 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Lua Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Lua Academy comprend 4 leçons au total.

Les quatre états d’une coroutine

Les coroutines peuvent se trouver dans quatre états : suspendue (créée ou après un yield, en attente d’exécution), en cours d’exécution (en train de s’exécuter), normale (en pause pour permettre à une autre coroutine de s’exécuter) et morte (terminée ou ayant rencontré une erreur). Interrogez l’état avec 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

L’état « normal »

Une coroutine entre dans l’état « normal » lorsqu’elle reprend une autre coroutine. Elle n’est pas en cours d’exécution, puisque c’est l’autre coroutine qui l’est, mais elle n’est pas non plus suspendue : elle attend que la coroutine reprise utilise yield. Cet état est rare, mais il est important de le comprendre dans les graphes de coroutines complexes.

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

Vérifier avant la reprise

Vérifiez toujours l’état d’une coroutine avant de la reprendre, en particulier dans les boucles. Reprendre une coroutine morte est une erreur. Reprendre une coroutine en cours d’exécution est également une erreur, car cela provoquerait une récursion infinie.

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

État après une erreur

Lorsqu’une erreur non interceptée se produit dans le corps d’une coroutine, coroutine.resume renvoie false et le message d’erreur. La coroutine passe à l’état « morte ». Elle ne peut pas être redémarrée : vous devez en créer une nouvelle si vous souhaitez réessayer.

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() renvoie true si la coroutine en cours d’exécution peut utiliser yield. Il renvoie false dans le thread principal et dans les fonctions C qui ne prennent pas en charge yield. Vérifiez toujours ce résultat avant d’utiliser yield si vous n’êtes pas certain du contexte.

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

Surveiller un ensemble de coroutines

Suivez un pool de coroutines et supprimez les coroutines mortes après chaque série de reprises. C’est la base d’un ordonnanceur de tâches.

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

Déboguer les coroutines

Utilisez des vérifications d’état pour instrumenter et déboguer le code fondé sur des coroutines. Affichez les transitions d’état pour comprendre le déroulement de l’exécution. Dans les systèmes complexes, attribuez des noms aux coroutines au moyen d’une table enveloppe afin d’obtenir une sortie de débogage plus claire.

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

Redémarrer des coroutines mortes

Une fois qu’une coroutine est morte, elle ne peut plus être reprise. Pour la « redémarrer », vous devez créer une nouvelle coroutine à partir de la même fonction. Un schéma courant consiste à utiliser une fabrique qui crée une coroutine vierge à la demande.

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

Gestion des erreurs de Coroutine.wrap

Lorsqu’une coroutine enveloppée rencontre une erreur, celle-ci se propage hors de l’appel de la fonction enveloppe. Contrairement à coroutine.resume, qui renvoie false+error, les fonctions renvoyées par wrap déclenchent directement l’erreur. Utilisez pcall autour des appels à wrap si vous devez intercepter les erreurs.

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 et status

Il existe deux façons d’inspecter le contexte d’une coroutine : coroutine.status(co) donne l’état d’une coroutine précise ; coroutine.isyieldable() indique si le contexte d’exécution actuel peut utiliser yield. Utilisez status pour vérifier les autres coroutines et isyieldable pour vérifier si vous pouvez utiliser yield en toute sécurité.

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

Vérification rapide

Dans quel état une coroutine entre-t-elle lorsqu’elle termine l’exécution de sa fonction principale ?

Récapitulatif : état des coroutines

Résumé :

  • États : suspendue → en cours d’exécution ↔ normale → morte
  • coroutine.status(co) renvoie la chaîne représentant l’état
  • Morte = terminée ou ayant rencontré une erreur ; elle ne peut pas être reprise
  • coroutine.isyieldable() vérifie si le contexte actuel peut utiliser yield
  • Vérifiez toujours l’état avant une reprise dans les boucles
  • Les erreurs de wrap se propagent directement ; resume renvoie false+err

Questions Fréquemment Posées

La leçon « État d’une coroutine » est-elle gratuite ?

Oui — le texte complet de « État d’une coroutine » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Lua Academy, passe à CoddyKit PRO. Le cours Lua Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « État d’une coroutine » ?

Vérifiez l’état d’une coroutine avec coroutine.status : running, suspended, dead. Tu pratiques Lua Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer Lua Academy ?

Aucune expérience préalable n'est requise. Lua Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 3 sur 4.

Combien de temps prend la leçon « État d’une coroutine » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon Lua Academy ?

Oui. Chaque leçon Lua Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Créer des coroutines
  2. resume et yield
  3. État d’une coroutine
  4. Modèle producteur-consommateur
← Retour à Lua Academy