![]() |
Programmation en language LUA |
Cours d'instruction de Coroutines |
Coroutines nous permettent d'exécuter plusieurs charge immédiatement. Ceci est fait d'une façon commandée en passant la main à chaque routine et l'attente jusqu'à ce que le courant indique de lui a fini. Nous pouvons réintroduire la routine pour continuer à un temps postérieur et en faisant ceci à plusieurs reprises nous réalisons multi-charger.
Chacun charge des courses dans un fil qui est séparé des autres fils. Ayant plusieurs charge le fonctionnement immédiatement s'appelle souvent multi-filetage. Puisqu'il y a plus d'un fil courant immédiatement notre application serait multi-fileté.
Il y a de différentes manières dont le multi-filetage peut être mis en application. Quelques systèmes assignent une quantité de temps fixe à chaque fil et enlèvent la commande quand le temps est en hausse, transmettant la commande au prochain fil etc... Ceci s'appelle multi-filetage de préemption. Dans ce cas-ci chacun des fils n'a pas besoin de s'inquiéter combien d'heure il occupe, il davantage est concerné par sa propre fonction.
Dans d'autres systèmes, un fil est concerné par combien de temps il prend. Le fil sait qu'il doit passer la main à d'autres fils de sorte qu'ils puissent fonctionner aussi bien. C'est s'appelle coopérative, ou multi-filetage de collaboration. Ici, tous les fils collaborent ensemble pour permettre à l'application de fonctionner correctement. C'est le type de multi-charger que les coroutines de Lua emploient.
Coroutines dans Lua ne sont pas des fils ou des processus de logiciel d'exploitation. Coroutines sont des blocs de code de Lua qui sont créés dans Lua, et ont leur propre écoulement de commande comme des fils. Seulement un coroutine fonctionne jamais à la fois, et il fonctionne jusqu'à ce qu'il active un autre coroutine, ou rapporte (des retours au coroutine qui l'a appelé). Coroutines sont une manière d'exprimer les fils de coopération multiples de la commande en manière commode et normale, mais ne s'exécutent pas en parallèle, et ne gagnent ainsi aucun avantage d'exécution de CPU's multiple. Cependant, depuis des coroutines commutez beaucoup plus rapidement que des fils de logiciel d'exploitation et n'exigez pas typiquement le complexe et les dispositifs de verrouillage parfois chers, employant des coroutines est en général plus rapide que le programme équivalent en utilisant de pleins fils d'OS.
Afin coroutines multiples pour partager
l'exécution qu'ils doivent cesser s'exécuter (après avoir effectué
une quantité sensible de traitement) et passer la main à un autre
fil. Cet acte de la soumission s'appelle rendement. Coroutines appellent
explicitement une fonction de Lua coroutine.yield()
, qui est semblable à
employer return
dans les fonctions. Ce qui différencie le
rendement des retours de fonction est celui à un point postérieur
que nous pouvons réintroduire le fil et continuer où nous avons
cessé. Quand vous sortez une portée de fonction employant return
la portée est détruit et nous ne pouvons pas la
réintroduire, par exemple,
> foo(x) de fonction > > si x>3 alors l'extrémité vraie de retour -- nous pouvons sortir la fonction avant que l'extrémité si besoin en est > > retour faux -- renvoyez une valeur à la fin de la fonction (facultative) > > extrémité > = foo(1) faux > = foo(100) -- point différent de sortie vrai
Pour créer un coroutine nous devons avoir la fonction qui le représente, par exemple,
> foo() de fonction > > print("foo", 1) > > coroutine.yield() > > print("foo", 2) > > extrémité >
Nous créons un coroutine en utilisant coroutine.create(fn)
la fonction. Nous lui passons un point d'entrée
pour le fil qui est une fonction de Lua. L'objet est retourné
par Lua est un fil:
> les Co = coroutine.create(foo) -- créez un coroutine avec le foo comme entrée > = type(co) -- montrent le type fil de l'objet de "Co"
Nous pouvons découvrir quel état le fil est en
employant coroutine.status()
la fonction, par exemple,
> = coroutine.status(co) suspendu
coroutine.resume()
la fonction. Lua entrera dans le
fil et partira quand le fil rapporte.
> = coroutine.resume(co) foo 1 vrai
coroutine.resume()
La fonction renvoie le statut d'erreur de
l'appel de résumé. Le rendement reconnaît que nous avons
écrit la fonction foo
et avons puis sorti sans des erreurs.
Est maintenant le peu intéressant. Avec une fonction nous
ne pourrions pas continuer où nous avons cessé, mais avec des
coroutines nous pouvons reprendre encore :
> = coroutine.resume(co) foo 2 vrai
foo
et sommes encore
retournés sans erreur. Cependant, si nous regardons le statut
nous pouvons voir que nous avons sorti la fonction foo
et le
coroutine terminés.
> = coroutine.status(co) morts
> = coroutine.resume(co) faux ne peut pas reprendre le coroutine mort
Ce qui suit est un exemple plus compliqué démontrant quelques dispositifs importants des coroutines.
> odd(x) de fonction > > print('A : impair ', x) > > coroutine.yield(x) > > print('B : impair ', x) > > extrémité > > even(x) de fonction > > print('C : même ', x) > > si extrémité de retour de x==2 puis x > > print('D : même ', x) > > l'extrémité > > Co = coroutine.create(> > la fonction (x) > > pour i=1, le x > > si puis coroutine.yield(-1) l'extrémité i==3 > > si puis extrémité d'autre d'odd(i) de l'even(i) math.mod(i, 2)==0 > > extrémité > > extrémité) > > compte = 1 > tandis que coroutine.status(co) le ~ = 'complètement ' > > compte du print('----') ; compte = count+1 > > errorfree, valeur = coroutine.resume(co, 5) > > print('E : errorfree, valeur, statuts, errorfree, valeur, coroutine.status(co)) > > extrémité 1 A : 1 E impair : l'errorfree, valeur, statut rectifient 1 suspendu 2 B : 1 C impair : égalisez 2 E : l'errorfree, valeur, statut rectifient -1 suspendu 3 A : 3 impairs E : l'errorfree, valeur, statut rectifient 3 suspendus 4 B : 3 impairs C : égalisez 4 D : égalisez 4 A : 5 impairs E : l'errorfree, valeur, statut rectifient 5 suspendus 5 B : 5 impairs E : errorfree, valeur, zéro vrai de statut mort >
Fondamentalement nous avons for
une
boucle qui appelle deux fonctions : odd()
quand elle rencontre
un nombre impair et even()
sur des chiffres pairs. Il peut
être peu un difficile digérer le rendement ainsi nous étudierons
les boucles externes, comptées près count
, une par une.
Des commentaires ont été ajoutés.
1 A : 1 impair -- rendement de l'odd() E : l'errorfree, valeur, statut rectifient 1 suspendu
coroutine.resume(co, 5)
. La première fois qu'il s'appelle nous
écrivons for
la boucle dans la fonction de coroutine.
Notez que la fonction odd()
, qui s'appelle par nos
rendements de fonction de coroutine. Vous ne devez pas rapporter
dans la fonction de coroutine. C'est un dispositif important et
utile. Nous renvoyons la valeur de 1 avec le rendement.
2 B : 1 impair -- résumé dans impair avec les valeurs que nous avons laissées sur le rendement C : même 2 -- appel égal et sortie pr3maturément E : l'errorfree, valeur, statut rectifient -1 suspendu -- rendement dedans pour la boucle
for
principale rapporte et suspend le coroutine. Le
point à la note ici est que nous pouvons rapporter n'importe où.
Nous ne devons pas maintenir rapporter d'un point dans notre
coroutine. Nous renvoyons -1 avec le rendement.
3 A : 3 impairs -- l'odd() rapporte encore après avoir repris dedans pour la boucle E : l'errorfree, valeur, statut rectifient 3 suspendus
for
la
boucle et quand odd()
s'appelle elle rapporte encore.
4 B : 3 impairs -- le résumé dans l'odd(), des valeurs variables a maintenu C : égalisez 4 -- même le called() D : même 4 -- aucun retour dans l'even() cette fois A : 5 impairs -- odd() appelé et un rendement E : l'errorfree, valeur, statut rectifient 5 suspendus
odd()
où nous avons cessé. Notez que les valeurs
variables sont préservées. La portée odd()
de la
fonction est préservée pendant un coroutine suspendent. Nous
traversons à la fin de even()
, cette fois sortant à la fin de
la fonction. Dans l'un ou l'autre cas, quand nous sortons une
fonction sans employer coroutine.yield()
, la portée et toutes ses
variables sont détruites. Seulement sur un rendement pouvons
nous reprenons.
5 B : 5 impairs -- encore appelé E impair : errorfree, valeur, zéro vrai de statut mort -- pour la boucle se termine >
De nouveau nous reprenons dedans odd()
.
Cette fois la boucle for
principale atteint la limite
de 5 que nous avons passés dans le coroutine. La valeur de 5 et for
l'état de boucle ont été préservés dans toute
l'exécution du coroutine. Un coroutine préserve sa propres
pile et état tandis que dans l'existance. Quand nous sortons
notre fonction de coroutine qu'il meurt et nous pouvons plus ne
l'employer.
![]() |
|