2.11 Koroutinen Korrektur einreichen Original anzeigen

Lua unterstützt Koroutinen. Eine Koroutine in Lua repräsentiert einen unabhängigen Thread der Ausführung. Im Gegensatz zu Multithread-Systemen hält eine Koroutine ihre Ausführung jedoch nur über den expliziten Aufruf einer "yield"-Funktion an.

Sie erzeugen eine Koroutine über einen Aufruf von coroutine.create. Dessen einziges Argument ist eine Funktion, welche die Hauptfunktion der Koroutine darstellt. Die create-Funktion erzeugt lediglich eine neue Koroutine und liefert einen Verweis auf diese (ein Objekt des Typs thread); sie startet nicht die Ausführung der Koroutine.

Wenn Sie zum ersten mal coroutine.resume aufrufen und als erstes Argument einen von coroutine.create zurückgegebenen Thread übergeben, startet die Koroutine ihre Ausführung bei der ersten Zeile ihrer Hauptfunktion. Zusätzliche Argumente, welche coroutine.resume übergeben werden, werden der Hauptfunktion der Koroutine durchgereicht. Nachdem die Koroutine gestartet ist, läuft diese, bis sie entweder beendet oder unterbrochen wird.

Eine Koroutine kann ihre Ausführung auf zwei Arten beenden: Normalerweise, wenn ihre Hauptfunktion beendet ist (explizit, oder implizit nach der letzten Anweisung) und im Sonderfall, wenn ein ungeschützter Fehler auftritt. Im ersten Fall liefert coroutine.resume true und alle Werte, welche von der Hauptfunktion der Koroutine geliefert werden. Im Fehlerfall liefert coroutine.resume false und eine Fehlernachricht.

Eine Koroutine hält durch einen Aufruf von coroutine.yield an. Wenn eine Koroutine anhält, gibt die zugehörige coroutine.resume sofort zurück, auch wenn das Anhalten in einem verschachtelten Funktionsaufruf (d. h. nicht in der Hauptfunktion, sondern einer Funktion, welche direkt oder indirekt durch die Hauptfunktion aufgerufen wurde) stattfand. Im Falle des Anhaltens liefert coroutine.resume ebenfalls true und sämtliche an coroutine.yield übergebenen Werte. Bei der nächsten Wiederaufnahme der Koroutine führt diese ihre Ausführung an der Stelle des Anhaltens mit einem Aufruf von coroutine.yield, welche sämtliche zusätzliche an coroutine.resume übergebenen Argumente zurückliefert, fort.

Wie coroutine.create erzeugt die coroutine.wrap-Funktion ebenfalls eine Koroutine, aber anstatt diese selbst zurückzuliefern, liefert sie eine Funktion, die wenn sie aufgerufen wird, die Koroutine wieder aufnimmt. Jegliche Argumente, welche dieser Funktion übergeben werden, gehen als zusätzliche Argumente an coroutine.resume. coroutine.wrap liefert alle Werte, welche von coroutine.resume geliefert werden, mit Ausnahme des ersten (der bool'sche Fehlercode). Im Gegensatz zu coroutine.resume fängt coroutine.wrap keine Fehler; jegliche Fehler werden an den Aufrufer gereicht.

Betrachten Sie beispielsweise folgenden Code:

function foo(a)
  print("foo",a)
  return coroutine.yield(2*a)
end

co = coroutine.create(function (a,b)
      print("co-body",a,b)
      local r = foo(a+1)
      print("co-body",r)
      local r,s = coroutine.yield(a+b,a-b)
      print("co-body",r,s)
      return b,"end"
end)

print("main",coroutine.resume(co,1,10))
print("main",coroutine.resume(co,"r"))
print("main",coroutine.resume(co,"x","y"))
print("main",coroutine.resume(co,"x","y"))

Wenn Sie diesen ausführen, wird folgende Ausgabe erzeugt:

co-body 1       10
foo     2

main    true    4
co-body r
main    true    11      -9
co-body x       y
main    true    10      end
main    false   cannot resume dead coroutine