⚠️ Les bases du langage doivent être bien maîtrisées avant d’aborder cette section. N’hésitez pas à relire plusieurs fois.
N’utilisez les coroutines que si vous savez ce que vous faites !
Les coroutines en Lua sont comparables aux threads en C, à une différence près :
plusieurs coroutines peuvent être créées, mais une seule peut s’exécuter à la fois. Lorsqu’une coroutine est active, elle bloque l’exécution du programme principal jusqu’à ce qu’elle rende la main.
Utilisation simple
1
2
3
4
5
6
7
8
9
10
11
|
function f()
print("Bonjour")
end
co = coroutine.create(f)
print(co)
coroutine.resume(co)
-- output :
-- thread: 0x64
-- Bonjour
|
Avec fonction anonyme
1
2
3
4
5
6
7
8
9
10
|
local co = coroutine.create(function()
print("Bonjour")
end)
print(co)
coroutine.resume(co)
-- output :
-- thread: 0xa8
-- Bonjour
|
Coroutine bloquante
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
function f()
print("Début de la coroutine")
local t0 = os.clock()
while os.clock() - t0 <= 5 do end
print("Fin de la coroutine")
end
co = coroutine.create(f)
coroutine.resume(co)
print("Fin du programme")
-- output :
-- Début de la coroutine
-- Fin de la coroutine (après 5s)
-- Fin du programme
|
États des coroutines
Utilisez coroutine.status()
pour vérifier l’état d’une coroutine :
État |
Signification |
suspended |
En pause |
running |
En cours d’exécution |
dead |
Terminée |
Une coroutine dead
ne peut plus être redémarrée.
coroutine.yield()
: mise en pause
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
function f()
for i = 0, 2 do
print(i)
coroutine.yield()
end
end
co = coroutine.create(f)
coroutine.resume(co)
coroutine.resume(co)
coroutine.resume(co)
print(coroutine.status(co))
coroutine.resume(co)
print(coroutine.status(co))
coroutine.resume(co) -- Erreur : coroutine morte
-- output :
-- 0
-- 1
-- 2
-- suspended
-- dead
-- cannot resume dead coroutine
|
Générateurs avec paramètres
1
2
3
4
5
6
7
8
9
|
function somme(a, b)
coroutine.yield(a + b)
end
co = coroutine.create(somme)
print(coroutine.resume(co, 6, 4))
-- output :
-- true 10
|
Itérateurs
Les coroutines peuvent être utilisées pour créer des itérateurs simples :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
function f()
local tab = {1, 2, 3, 4, 5}
for i = 1, #tab do
coroutine.yield(tab[i])
end
end
co = coroutine.create(f)
while true do
local code, res = coroutine.resume(co)
if not code then break end
print(res)
end
-- output :
-- 1
-- 2
-- 3
-- 4
-- 5
|
Ces exemples sont volontairement simples. Les coroutines permettent bien d’autres usages, que nous aborderons dans des tutoriels plus avancés.