Latest web development tutorials

Lua Koroutinen (Koroutine)

Was ist eine synergistische (Koroutine)?

Lua Koroutinen (Koroutine) Gewinde relativ ähnlich: ein unabhängiger Stapel, lokale Variablen separate, unabhängige Befehlszeiger, sondern auch gemeinsame globale Variablen, und die meisten anderen Dinge und andere Kooperationsprogramme.

Synergy ist sehr leistungsfähig, aber auch sehr kompliziert zu bedienen.

Der Unterschied zwischen den Threads und Koroutinen

Der Hauptunterschied zwischen den Threads und Koroutinen, dass ein Programm mehrere Threads hat, kann mehrere Threads gleichzeitig ausgeführt werden, während Kooperationsprogramm über eine andere Zusammenarbeit benötigen würde.

Zu jedem gegebenen Zeitpunkt ist nur ein kooperatives Programm läuft, und die Lauf coroutine nur die suspendierten Zeit erforderlich zu löschen wird ausgesetzt.

Collaborative Programm ein wenig ähnlich mehreren Threads im selben Thread zu synchronisieren für die Sperre mehrere Threads etwas ähnliche Zusammenarbeit warten.

Die grundlegende Syntax

Weg Beschreibung
coroutine.create () Erstellen Sie eine Koroutine, Rückkehr Koroutine, Argument ist eine Funktion, wenn sie in Verbindung mit diesen verwendet und wieder aufnehmen, wenn die Wake-up-Funktion aufruft
coroutine.resume () Starten Sie Koroutine, und erstellen Sie mit der Verwendung von
coroutine.yield () Abgehängte Koroutine, der Koroutine Zustand anhängig und Fortsetzen mit der Verwendung dieser viele nützliche Wirkung haben
coroutine.status () Überprüfen Sie den Status Koroutine HINWEIS: Koroutine Zustand gibt es drei: tot, aussetzen, laufen, vor allem, wenn es einen solchen Zustand ist, lesen Sie bitte die folgenden Verfahren
coroutine.wrap () Erstellen Sie eine Koroutine, gibt eine Funktion, die Sie einmal diese Funktion aufzurufen, geben Sie Koroutine, und erstellen Sie Repeat-Funktion
coroutine.running () Returns laufen Koroutine, ein Koroutine ist ein Thread, beim Laufen, wenn der Thread ist eine Reihe von corouting zurückzukehren

Das folgende Beispiel zeigt die Verwendung von jedem der oben genannten Verfahren:

-- 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("----------")

Beispiele für die Durchführung der oben genannten Ausgabe ist:

1
dead
----------
1
----------
1
2
3
running
thread: 0x7fb801c05868	false
suspended
thread: 0x7fb801c04c88	true
----------

coroutine.running zu sehen ist, ist Koroutine Umsetzung am Boden ein Thread.

Wenn ein Koroutine erstellen, wenn ein Ereignis in den neuen Thread registriert ist.

Wenn ein Wiederaufnahmeereignis ausgelöst wird, wenn Erstellen Sie eine Koroutine Funktion ausgeführt wird, und wenn es mit dem Ertrag im Namen konfrontiert bricht den aktuellen Thread wieder zu warten, wieder aufnehmen Ereignis ausgelöst wird.

Als nächstes analysieren wir ein detaillierteres Beispiel:

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("---分割线---")

Beispiele für die Durchführung der oben genannten Ausgabe ist:

第一次协同程序执行输出	1	10
foo 函数输出	2
main	true	4
--分割线----
第二次协同程序执行输出	r
main	true	11	-9
---分割线---
第三次协同程序执行输出	x	y
main	true	10	结束协同程序
---分割线---
main	false	cannot resume dead coroutine
---分割线---

Beispiele übernahm wie folgt:

  • Anrufwiederaufnahme-, koordiniert Wakeup, fortsetzen die Operation erfolgreich return true, sonst return false;
  • Collaborative Programm läuft;
  • Führen Sie Anweisungen zu erhalten;
  • Ausbeute suspendierte Koroutine ersten Lebenslauf zurückkehrt; (Hinweis: yield return hier wieder aufnehmen Parameter sind Parameter)
  • Zweite Lebenslauf, wieder aufwachen Koroutinen; (Hinweis: Dieser Lebenslauf Parameter, zusätzlich zu dem ersten Argument, die restlichen Parameter als Parameter ergeben)
  • Ausbeute zurückkehrt;
  • Collaborative Programm läuft weiter;
  • Wenn Sie weiterhin das kooperative Programm ausführen verwendet das Verfahren wieder aufnehmen nach der Beendigung der Ausgabe zu rufen weiter: kann nicht fortgesetzt werden tot Koroutine

Die Macht der Platz mit dem Lebenslauf und Ertrag, Lebenslauf im Hauptprogramm, wird es außerhalb des Staates (Daten) werden, um die internen Koordinierungsverfahren geführt und werden die internen Zustand (Daten) ergeben kehrt zu dem Hauptprozess.


Hersteller - Verbraucherfragen

Die Verbraucher dieses klassische Problem - ich werde jetzt vervollständigen die Hersteller Lua Koroutinen verwenden.

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()

Beispiele für die Durchführung der oben genannten Ausgabe ist:

1
2
3
4
5
6
7
8
9
10
11
12
13
……