0Pricing
Lua Academy · Leçon

Créer des coroutines

Créez des coroutines avec coroutine.create et coroutine.wrap.

Créer des coroutines est une leçon Lua Academy gratuite sur CoddyKit. Ceci est la leçon 1 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.

Qu'est-ce qu'une coroutine ?

Une coroutine est une fonction qui peut suspendre son exécution (yield), puis la reprendre là où elle s'était arrêtée. Contrairement aux threads, les coroutines sont coopératives : une seule s'exécute à la fois et elles cèdent explicitement le contrôle. Les coroutines Lua disposent de leur propre pile et de leurs propres 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 contre coroutine.wrap

coroutine.create(fn) crée une coroutine et renvoie un objet coroutine (de type thread). coroutine.wrap(fn) crée une coroutine et renvoie une fonction qui la reprend lorsqu'elle est appelée. wrap est plus simple, mais masque l'objet 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

Cycle de vie d'une coroutine

Une coroutine possède quatre états : suspendue (elle ne s'exécute pas), en cours d'exécution (elle s'exécute actuellement), terminée (elle a renvoyé une valeur ou produit une erreur) et normale (elle est en pause parce qu'elle a repris une autre coroutine). Vérifiez son état avec 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

Exécuter plusieurs coroutines

Créez plusieurs coroutines et entremêlez leur exécution en reprenant chacune à son tour. Cela simule une exécution concurrente (multitâche coopératif). Chaque coroutine conserve son propre état entre deux appels à yield.

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

Itération avec coroutine.wrap

coroutine.wrap est couramment utilisé pour créer des itérateurs. La fonction renvoyée est appelée chaque fois que l'itérateur avance. Lorsque le corps de la coroutine se termine, la fonction produit une erreur — utilisez pcall ou vérifiez l'état si nécessaire.

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

Erreur dans les coroutines

Si une coroutine produit une erreur, coroutine.resume renvoie false, suivi du message d'erreur. La coroutine passe à l'état dead. Une coroutine terminée ne peut plus être reprise.

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é d'une coroutine

coroutine.running() renvoie la coroutine en cours d'exécution ainsi qu'un booléen indiquant s'il s'agit du thread principal. Utilisez cette fonction dans une coroutine pour obtenir une référence à elle-même.

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

Générateur infini

Le corps d'une coroutine peut contenir une boucle infinie avec des appels à yield — le générateur produit des valeurs à la demande sans jamais se terminer. Il s'agit d'un cas d'utilisation essentiel : les séquences infinies et différées.

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

Les coroutines comme tâches

Un planificateur de tâches élémentaire consiste à stocker les coroutines dans une file d'attente et à reprendre chacune à son tour. Lorsqu'une coroutine produit une valeur avec yield, elle retourne dans la file. Lorsqu'elle se termine, elle en est retirée. Il s'agit d'un planificateur coopératif minimal.

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

Mémoire des coroutines

Chaque coroutine possède sa propre pile. Les piles peuvent devenir volumineuses lorsque les chaînes d’appels sont profondes. Dans les situations exigeant de hautes performances, évitez de créer des milliers de coroutines actives simultanément. Réutilisez les coroutines lorsque c’est possible ou utilisez des 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")

Vérification rapide

Dans quel état se trouve une coroutine immédiatement après coroutine.create(fn) ?

Récapitulatif : créer des coroutines

Résumé :

  • coroutine.create(fn) → objet coroutine ; wrap(fn) → fonction pouvant être reprise
  • États : suspendue → en cours d’exécution → suspendue/morte
  • coroutine.resume(co, ...) démarre ou reprend l’exécution
  • Erreurs pendant la reprise : false + message d’erreur ; la coroutine devient morte
  • Générateurs infinis avec while true do yield() end
  • À utiliser pour le multitâche coopératif et les séquences paresseuses

Questions Fréquemment Posées

La leçon « Créer des coroutines » est-elle gratuite ?

Oui — le texte complet de « Créer des coroutines » 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 « Créer des coroutines » ?

Créez des coroutines avec coroutine.create et coroutine.wrap. 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 1 sur 4.

Combien de temps prend la leçon « Créer des coroutines » ?

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