Pourquoi parler de stratégie de coroutine et non de coroutine en Lua ?
La raison principale est que le concept réel de coroutine n’existe pas tout à fait en Lua. En effet, les coroutines en Lua sont monothread, autrement dit asymétriques.
Contrairement aux threads traditionnels, qui permettent une exécution parallèle, les coroutines en Lua fonctionnent dans un seul thread et exigent une gestion explicite du passage de contrôle. Cela signifie qu'une coroutine ne reprend son exécution que lorsqu'elle est explicitement réactivée par l'appelant via coroutine.resume(). Inversement, une coroutine suspend son exécution volontairement en appelant coroutine.yield().
Une gestion explicite du passage de contrôle
L'utilisation des coroutines repose donc sur une stratégie bien définie pour organiser la coopération entre différentes parties du programme. Par exemple, elles sont souvent employées pour :
- Implémenter des itérateurs
 - Mettre en place des systèmes de gestion d'événements
 - Créer des mécanismes de planification de tâches non bloquantes style une requête web asynchrone
 
Stratégie d'utilisation des coroutines
Une bonne stratégie d'utilisation des coroutines en Lua implique de structurer son code de manière à minimiser les points de blocage et à garantir une reprise fluide de l'exécution. Par exemple, dans un jeu vidéo, les coroutines peuvent être utilisées pour gérer :
- Des animations
 - Des comportements d'intelligence artificielle
 
Cela permet d'éviter de bloquer le fil principal d'exécution.
Simuler de la concurrence
Bien que Lua n’offre pas de multitraitement natif, il est possible de combiner les coroutines avec des bibliothèques externes ou des threads en C pour simuler une exécution concurrente. Cependant, cela demande une gestion soigneuse des ressources partagées et une coordination efficace entre les différents processus en cours d'exécution.
La bibliothèque coroutine permet de créer, démarrer et suivre des routines dans le cadre de la gestion de l'exécution concurrente en Lua.
1. coroutine.create(function : Function)
Description
Cette fonction permet de créer une routine à partir d'une fonction.
Une routine représente une séquence d'exécution qui peut être mise en pause et reprise.
Paramètres
- 
function: Une fonction Lua qui contient le code à exécuter dans la routine. 
Retour
- Retourne un objet 
Routinequi représente la routine créée. 
Example
local routine = coroutine.create(function()
    print("Cette routine est exécutée !")
end)
2. coroutine.resume(routine:Routine,args:...?)
Description
Cette fonction permet d'executé une routine
Paramètres
- 
routine: la routine à exécuter - 
args: un ensemble d'argument associer à la fonction dans laroutineou des données injecter dans lapauseprécédent 
Retours
- Succès d'éxécution de la 
routine - Message d'erreur de la 
routine(falcultatif) - 
argsun ensemble d'argument associer aux des données injecter dans lapauseprécédent (falcultatif) 
Example simple
local routine = coroutine.create(function(qui,message)
    print(qui,message)
end)
Coroutine.resume(routine,"Yoda","Bonjour  maître Yoda")
Yoda    Bonjour  maître Yoda
Example avec une erreur
local routine = coroutine.create(function(qui,message)
    print(qui,message)
end)
coroutine.resume(routine,"Yoda","Bonjour maître Yoda")
local estBienExecuter, messageErreur = coroutine.resume(routine)
print(estBienExecuter, messageErreur)
Yoda    Bonjour maître Yoda
false   cannot resume dead coroutine
3.coroutine.status(routine:Routine)
Description
Permet d'obtenir le status de la Routine
- 
suspended: la routine est disponible, mais non utilisé - 
running: la routine est en cours d'exécution - 
normal: lorsque la routine est lancer par une autre - 
dead: la routine est morte 
Paramètres
- 
Routine: la routine à exécuter 
Retour
- 
Status : 
suspended,runningoudead 
Examples de cycle de vie d'une routine
local status = {
    avant = nil,
    pendant = nil,
    apres = nil
}
local routine, bienvenue
bienvenue = function(nom)
    print("Bonjour",nom)
    status.pendant = coroutine.status(routine)
end
routine = coroutine.create(bienvenue)
status.avant = coroutine.status(routine)
coroutine.resume(routine,"Léo")
status.apres = coroutine.status(routine)
for etape,etat in pairs(status) do print(etape,etat) end
Bonjour Léo
avant   suspended
pendant running
apres   dead
4. coroutine.yield(args:...?)
Description
Permet de mettre en pause une routine pour son prochain apelle. 
Permet l'échapement et l'injection de données vers une Routine
Paramètres
args : un ensemble d'argument associer à la fonction dans les pareméetre de yield pour l'éhcapement et comme assignation pour l'injection(falcultatif)w
Retour
args : un ensemble d'argument associer à la fonction dans les pareméetre de yield pour l'éhcapement (falcultatif)
pause de la routine
Conseil
pour savoir le nombre de coroutine.resume à faire. compter le nombre de coroutine.yield + 1 dans votre fonction.
Example échapement
local routine = coroutine.create(function()
    coroutine.yield("données échaper")
end)
local estExecuter, donneExtrapoler = coroutine.resume(routine)
print(donneExtrapoler)
données échaper
Example injection
local routine = coroutine.create(function()
    local x = coroutine.yield()
    print(x)
end)
coroutine.resume(routine)
coroutine.resume(routine,"Données injecter")
Données injecter
5. coroutine.wrap(function:Function)
Description
Permet de créer une fonction avec un comportement de routine sans être une routine
Paramètres
- 
Fonction: la fonction avec lespause 
Retour
- 
argsun ensemble d'argument associer aux des données injecter dans lapauseprécédent (falcultatif) 
Example
routine = coroutine.wrap(function()
    print("Étape 1")
    local reponse = coroutine.yield("Bonjour maître Yoda")
    print("Étape 2 - "..reponse)
    coroutine.yield()
    print("Étape 3")
end)
local data = routine()
print(data)
routine("Bonjour Luc")
routine()
Étape 1
Bonjour maître Yoda
Étape 2 - Bonjour Luc
Étape 3
6. coroutine.close(routine:Routine)
Description
permet de tuer votre routine
Paramètres
- 
Routine: la routine à tuer 
Retour
- 
boolean:truesi la routine existe 
Example
local routine = coroutine.create(function()
    print("Dans la coroutine, c'est :", 
        coroutine.running()-- Affiche l'ID de la coroutine
    )
end)
coroutine.close(routine)
print(coroutine.resume(routine))
false   cannot resume dead coroutine
Références
- Roberto Ierusalimschy, « 9.1 – Coroutine Basics », lua.org, https://www.lua.org/pil/9.1.html
 - Inconnu, « Lua - Coroutines », www.tutorialspoint.com, https://www.tutorialspoint.com/lua/lua_coroutines.htm
 - Sylvain Fabre et al., Le guide de lua et ses applications : Manuel d'apprentissage, D-Booker, 04/2016, pages 65-67.
 
Commentaires1
Salut Léo, ton article sur…
Salut Léo, ton article sur les coroutines en Lua est vraiment bien ficelé ! J'apprécie particulièrement la façon dont tu as structuré l'information pour la rendre accessible, même pour quelqu'un qui débute avec ce concept. Ta présentation des coroutines comme étant monothread et asymétriques est un point fort. Ça aide vraiment à comprendre pourquoi on parle de "stratégie de coroutine" plutôt que de multitâche concurrent. Bien joué ! J'ai trouvé très utile ton explication détaillée des fonctions de la bibliothèque coroutine, avec des exemples concrets à l'appui. Ça rend le tout beaucoup plus tangible. Ce que j'ai particulièrement apprécié : Ta distinction claire entre coroutines et threads classiques. Ça évite pas mal de confusions ! Tes exemples de code sont limpides et illustrent parfaitement le fonctionnement de chaque fonction. J'ai adoré la partie sur les cas d'utilisation concrets (animations, IA, requêtes asynchrones). Ça donne vraiment envie d'essayer ! Bref, c'est un super article qui m'a permis de mieux saisir l'intérêt et le fonctionnement des coroutines en Lua. Merci pour ce travail de qualité, Léo !