Latest web development tutorials

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
……