Lua: Le tutoriel  wxWidgets
Lua
Les coroutines: Les bases de fonctionnement.

Vous retrouverez toutes les fonctions utiles aux coroutines dans la bibliothèque Lua: Fonctions sur les coroutines.

La fonction coroutine.create(), crée une nouvelle coroutine et retourne une valeur de type thread, qui représente la nouvelle coroutine.

Le plus souvent, l'argument de la fonction coroutine.create() est une fonction anonyme.

		co = coroutine.create( function()
			print("bonjour")
		end)
		
			print(co)    --> thread: 0x8071d98
				

Une coroutine dispose de trois états différents:

suspended en attente.
runningen fonctionnement.
dead .. morte! ..

Lorsque vous créez une coroutine, elle est automatiquement suspended.. en attente de vos ordres.

La fonction coroutine.status(nom de la coroutine) vérifie son état.

La fonction coroutine.resume(nom de la coroutine) démarre son exécution.

La coroutine démarre et fait ce pour quoi elle a été créée, puis s'arrête..c'en est fini pour elle, elle est dead! (morte)

Jusqu'à présent, les coroutines ne ressemblent à rien de plus qu'à une manière compliquée d'appeler des fonctions.

La vraie puissance des coroutines provient de la fonction coroutine.yield, qui autorise une reprise ultérieure de son fonctionnement.

		co = coroutine.create( function()
			for i = 1, 10 do
				print("co", i)
				coroutine.yield()
			end
		end)
					

La coroutine est créée, mais elle ne fait rien, elle attend...coroutine.resume(co) qui va exécuter une 1ère boucle, puis la coroutine coroutine.yield va mettre la suite en suspend et attendre de nouveau vos ordres.

A chaque coroutine.resume(co), co fera un tour, s'arrêtera et attendra de nouveau... jusqu'à ce que la boucle soit bouclée.
Elle a fait ses 10 tours, maintenant, elle est morte!
Vous ne pouvez plus rien en faire, elle ne redémarrera plus.
Vous ne pouvez pas relancer une coroutine dead.

Notez que coroutine.resume fonctionne en mode protégé. Par conséquent, s'il y a une erreur dans une coroutine, Lua ne pourra pas afficher de message d'erreur, mais reviendra à la fonction d'appel.

Une fonctionnalité utile en Lua est que cette paire resume-yield peut échanger des données.

Le premier resume qui n'a pas encore rencontré le premier yield peut lui envoyer ses propres arguments en tant que extra-argument de la fonction principale.
L'exemple suivant permettra de mieux clarifier ces propos.

		co = coroutine.create( function(a, b, c)
			coroutine.yield(a + b, a - b)				
		end)
		
		print( coroutine.resume(co, 20, 10)) true 30  10
				
Symétriquement, yield retourne les arguments supplémentaires passés par resume.
		co = coroutine.create( function()
			print("co", coroutine.yield()
		end)

		coroutine.resume(co)
		coroutine.resume(co, 4, 5))  
		--> co  4  5
				
Enfin, lorsqu'une coroutine se termine, toutes les valeurs retournées par sa fonction principale, s'ajoutent à la correspondance de resume.
		co = coroutine.create(function()
			return 6, 7
		end)

		print(coroutine.resume(co))
		true  6  7
				

Vous aurez rarement l'occasion d'utiliser tous ces équipements dans une même coroutine, mais il est bon de savoir qu'ils existent.

Il est maintenant important de clarifier certains concepts avant de poursuivre.

Lua offre des coroutines asymétriques.

Cela signifie qu'il existe une fonction pour suspendre l'exécution d'une coroutine et une fonction différente pour reprendre la coroutine suspendue.

Contrairement à certains autres langages qui offrent des coroutines symétriques, où il existe seulement une seule fonction de transfert du contrôle d'une coroutine à l'autre.

Certaines personnes appellent les coroutines asymétriques, des demi-coroutines (parce qu'elles ne sont pas symétriques..).

Mais, d'autres personnes utilisent le même terme de semi-coroutine pour dénoter une application restreinte de coroutines, comme par exemple une coroutine qui pourrait suspendre son exécution que si elle est à l'intérieur d'une fonction auxiliaire, c'est-à-dire, quand elle a ses appels en attente dans sa pile de contrôle...

En d'autres termes, seul le corps principal de ces semi-coroutines peut utiliser yield.
Un générateur "Python" est un exemple de ce sens de semi-coroutines.

Contrairement à la différence entre les coroutines symétriques et asymétriques, la différence entre les coroutines et générateurs (tel que présenté en Python) est profonde.

Les générateurs ne sont tout simplement pas assez puissants pour mettre en oeuvre plusieurs constructions intéressantes que nous pouvons écrire avec les coroutines.

Lua offre de véritables coroutines asymétriques.
Ceux qui préfèrent utiliser les coroutines symétriques peuvent les implémenter en les installant sur le dessus des coroutines asymétriques de Lua.
C'est une tâche facile, car basiquement, chaque transfert d'un yield est suivie d'un resume.

logo wxWidgets Le savoir ne vaut que s'il est partagé par tous...
logo-internet_32x32.png Dernière mise à jour, le 14 décembre 2012.
Valid XHTML 1.0 Transitional

wxlualogo
Flèche haut
Flèche gauche
Flèche haut
Flèche droite