coroutines Lua (de coroutine)
Qu'est-ce qu'un synergique (coroutine)?
Lua coroutines (coroutine) Discussion relativement semblable: une pile indépendante, les variables locales distinctes, pointeur d'instruction indépendant, mais aussi des variables globales partagées, et la plupart des autres choses et d'autres programmes de collaboration.
Synergy est très puissant, mais aussi très compliqué à utiliser.
La différence entre les threads et coroutines
La principale différence entre les threads et coroutines qu'un programme a plusieurs threads peuvent exécuter plusieurs threads simultanément, tout programme de coopération aurait besoin d'une autre collaboration.
À un moment donné il n'y a qu'un programme de coopération est en cours d'exécution, et que seul le coroutine en cours d'exécution est nécessaire pour effacer le temps suspendu sera suspendu.
programme de collaboration quelque peu similaire à synchroniser plusieurs threads dans le même fil d'attente pour les verrous plusieurs threads de collaboration quelque peu similaire.
La syntaxe de base
manière | description |
---|---|
coroutine.create () | Créer un coroutine, retour coroutine, l'argument est une fonction, lorsqu'il est utilisé en conjonction avec, et reprendre lorsque les appels de fonction réveil |
coroutine.resume () | Redémarrez coroutine, et créer avec l'utilisation de |
coroutine.yield () | coroutine suspendu, le coroutine à l'attente de l'état et de reprendre avec l'utilisation de ce pour avoir beaucoup d'effet utile |
coroutine.status () | Vérifiez l'état de coroutine NOTE: état coroutine, il y a trois: morts, suspendre, en cours d'exécution, en particulier quand il y a un tel état, s'il vous plaît se référer aux procédures suivantes |
coroutine.wrap () | Créer un coroutine, retourne une fonction qu'une fois que vous appelez cette fonction, entrez coroutine, et de créer la fonction de répétition |
coroutine.running () | Les rendements sont en cours d'exécution coroutine, un coroutine est un fil, quand en cours d'exécution lorsque le fil est de retourner un certain nombre de corouting |
L'exemple suivant illustre l'utilisation de chacun des procédés ci-dessus:
-- coroutine_test.lua 文件 co = coroutine.create( function(i) print(i); end ) coroutine.resume(co, 1) -- 1 print(coroutine.status(co)) -- dead print("----------") co = coroutine.wrap( function(i) print(i); end ) co(1) print("----------") co2 = coroutine.create( function() for i=1,10 do print(i) if i == 3 then print(coroutine.status(co2)) --running print(coroutine.running()) --thread:XXXXXX end coroutine.yield() end end ) coroutine.resume(co2) --1 coroutine.resume(co2) --2 coroutine.resume(co2) --3 print(coroutine.status(co2)) -- suspended print(coroutine.running()) print("----------")
Des exemples de mise en oeuvre du résultat ci-dessus est la suivante:
1 dead ---------- 1 ---------- 1 2 3 running thread: 0x7fb801c05868 false suspended thread: 0x7fb801c04c88 true ----------
coroutine.running peut être vu, la mise en œuvre coroutine est un fil en bas.
Lorsque créer un coroutine lorsqu'un événement est enregistré dans le nouveau thread.
Quand un événement de reprise est déclenchée lorsque, créer une fonction coroutine est exécutée, et face au rendement au nom suspend le thread courant à attendre encore reprendre événement déclencheur.
Ensuite, nous analysons un exemple plus détaillé:
function foo (a) print("foo 函数输出", a) return coroutine.yield(2 * a) -- 返回 2*a 的值 end co = coroutine.create(function (a , b) print("第一次协同程序执行输出", a, b) -- co-body 1 10 local r = foo(a + 1) print("第二次协同程序执行输出", r) local r, s = coroutine.yield(a + b, a - b) -- a,b的值为第一次调用协同程序时传入 print("第三次协同程序执行输出", r, s) return b, "结束协同程序" -- b的值为第二次调用协同程序时传入 end) print("main", coroutine.resume(co, 1, 10)) -- true, 4 print("--分割线----") print("main", coroutine.resume(co, "r")) -- true 11 -9 print("---分割线---") print("main", coroutine.resume(co, "x", "y")) -- true 10 end print("---分割线---") print("main", coroutine.resume(co, "x", "y")) -- cannot resume dead coroutine print("---分割线---")
Des exemples de mise en oeuvre du résultat ci-dessus est la suivante:
第一次协同程序执行输出 1 10 foo 函数输出 2 main true 4 --分割线---- 第二次协同程序执行输出 r main true 11 -9 ---分割线--- 第三次协同程序执行输出 x y main true 10 结束协同程序 ---分割线--- main false cannot resume dead coroutine ---分割线---
Des exemples ont repris comme suit:
- Appelez CV, coordonnera réveil, reprendre l'opération retour réussi vrai, sinon return false;
- exécute des programmes de collaboration;
- Exécuter pour obtenir des déclarations;
- rendement suspendu coroutine rendements premier CV; (Note: le rendement retour ici pour reprendre les paramètres sont des paramètres)
- Deuxième CV, suite coroutines à nouveau; (Note: les paramètres Ce CV, en plus du premier argument, les autres paramètres donnera comme paramètre)
- rendements de rendement;
- programme de collaboration continue de fonctionner;
- Si vous continuez à exécuter le programme de coopération utilise la méthode continue d'appeler CV après l'achèvement de la sortie: ne peut pas reprendre coroutine mort
La puissance du lieu avec ce CV et le rendement, reprise dans le programme principal, il sera hors de l'Etat (données) transmises aux procédures internes de coordination, et donnera l'état interne (données) revient au processus principal.
les questions de consommation - Producteur
Les consommateurs de ce problème classique - je vais maintenant terminer les producteurs utilisent coroutines Lua.
local newProductor function productor() local i = 0 while true do i = i + 1 send(i) -- 将生产的物品发送给消费者 end end function consumer() while true do local i = receive() -- 从生产者那里得到物品 print(i) end end function receive() local status, value = coroutine.resume(newProductor) return value end function send(x) coroutine.yield(x) -- x表示需要发送的值,值返回以后,就挂起该协同程序 end -- 启动程序 newProductor = coroutine.create(productor) consumer()
Des exemples de mise en oeuvre du résultat ci-dessus est la suivante:
1 2 3 4 5 6 7 8 9 10 11 12 13 ……