0Pricing
Lua Academy · Lektion

resume und yield

Tauschen Sie mit resume/yield Daten zwischen Aufrufer und Coroutine aus

resume und yield ist eine kostenlose Lua Academy-Lektion auf CoddyKit. Dies ist Lektion 2 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Lua Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Lua Academy-Kurs umfasst insgesamt 4 Lektionen.

Werte an eine Coroutine übergeben

Argumente, die an das erste coroutine.resume übergeben werden, werden zu den Parametern der Coroutine-Funktion. Argumente, die an nachfolgende Aufrufe von resume übergeben werden, werden vom Aufruf coroutine.yield() zurückgegeben, der die Coroutine angehalten hat.

local co = coroutine.create(function(a, b)
  print("received:", a, b)        -- 10  20
  local c = coroutine.yield()     -- pauses
  print("after yield:", c)        -- 30
end)

coroutine.resume(co, 10, 20)  -- first call: passes a,b
coroutine.resume(co, 30)      -- subsequent: passed to yield

Werte von yield

Werte, die an coroutine.yield(val1, val2) übergeben werden, werden zu den Rückgabewerten des Aufrufs coroutine.resume(), der bei yield angehalten wurde. yield gibt also Werte an den Aufrufer zurück.

local co = coroutine.create(function()
  coroutine.yield(1, "hello")
  coroutine.yield(2, "world")
  return 3, "done"
end)

local ok, a, b = coroutine.resume(co)
print(ok, a, b)   -- true  1  hello

ok, a, b = coroutine.resume(co)
print(ok, a, b)   -- true  2  world

ok, a, b = coroutine.resume(co)
print(ok, a, b)   -- true  3  done

Bidirektionale Kommunikation

Coroutines ermöglichen echte bidirektionale Kommunikation: Der Aufrufer übergibt Daten über resume, die Coroutine verarbeitet sie und gibt Ergebnisse über yield zurück. Jeder resume-/yield-Aufruf ist ein synchroner Austausch.

local co = coroutine.create(function(x)
  while true do
    x = coroutine.yield(x * x)  -- yield x^2, get next x
  end
end)

coroutine.resume(co)  -- start (x=nil initially)
local ok, sq
ok, sq = coroutine.resume(co, 3); print(sq)  -- 9
ok, sq = coroutine.resume(co, 5); print(sq)  -- 25
ok, sq = coroutine.resume(co, 7); print(sq)  -- 49

Produzent und Konsument

Das klassische Coroutine-Muster: Der Produzent gibt Elemente einzeln über yield zurück; der Konsument setzt den Produzenten fort, sobald er das nächste Element benötigt. Keiner läuft dem anderen voraus – perfekte Synchronisation.

local function producer(items)
  return coroutine.create(function()
    for _, item in ipairs(items) do
      coroutine.yield(item)
    end
  end)
end

local pro = producer({"apple","banana","cherry"})

-- Consumer drives the loop
while true do
  local ok, item = coroutine.resume(pro)
  if not ok or item == nil then break end
  print("consumed:", item)
end

Pipeline mit Coroutines

Verketten Sie mehrere Coroutines zu einer Pipeline. Jede Stufe liest aus der vorherigen und gibt Werte an die nächste zurück. Die letzte Stufe steuert die Pipeline, indem sie die letzte Coroutine fortsetzt, wodurch sich der Aufruf durch die Kette zurückverfolgt.

local function source(items)
  return coroutine.wrap(function()
    for _, v in ipairs(items) do coroutine.yield(v) end
  end)
end

local function filter(iter, pred)
  return coroutine.wrap(function()
    for v in iter do
      if pred(v) then coroutine.yield(v) end
    end
  end)
end

local function map(iter, fn)
  return coroutine.wrap(function()
    for v in iter do coroutine.yield(fn(v)) end
  end)
end

local pipeline = map(filter(source({1,2,3,4,5,6}),
  function(n) return n%2==0 end),
  function(n) return n*n end)

for v in pipeline do io.write(v.." ") end
print()  -- 4 16 36

Coroutines zur Simulation asynchroner Abläufe

Ohne Betriebssystem-Threads können Coroutines asynchrone Vorgänge simulieren: Während des „Wartens“ wird yield aufgerufen und die Coroutine fortgesetzt, sobald das „Ergebnis“ bereitsteht. Ein Scheduler setzt die Coroutine mit dem Ergebnis fort.

local scheduler = {}
local current = nil

local function await(key)
  coroutine.yield(key)  -- tell scheduler what we need
  return coroutine.yield()  -- wait for result
end

local co = coroutine.create(function()
  local data = await("fetch:users")
  print("Got users:", data)
end)

-- Start coroutine
local ok, want = coroutine.resume(co)
print("Coroutine wants:", want)  -- fetch:users
-- Simulate delivering the result:
coroutine.resume(co, {{name="Alice"},{name="Bob"}})

yield innerhalb einer Funktion

Sie können yield innerhalb jeder von einer Coroutine aufgerufenen Funktion verwenden, nicht nur in der Funktion der obersten Ebene. Der yield-Aufruf wandert durch alle verschachtelten Aufrufe zurück bis zum resume-Aufruf. Dies wird als „angehaltener Aufruf-Stack“ bezeichnet.

local function yieldTwice(label)
  coroutine.yield(label .. ":1")
  coroutine.yield(label .. ":2")
end

local co = coroutine.create(function()
  yieldTwice("A")
  yieldTwice("B")
end)

for i = 1, 4 do
  local ok, v = coroutine.resume(co)
  print(v)
end
-- A:1, A:2, B:1, B:2

Coroutines sind keine Threads

Lua-Coroutines sind keine Betriebssystem-Threads. Es läuft immer nur eine Coroutine gleichzeitig; es gibt weder Präemption noch Parallelität. Alle Coroutines teilen sich einen einzigen Betriebssystem-Thread. Für echte Parallelität benötigen Sie mehrere Lua-Zustände in getrennten Betriebssystem-Threads.

-- This is NOT parallel - interleaved execution
local function task(name, n)
  for i = 1, n do
    print(name, i)
    coroutine.yield()
  end
end

local t1 = coroutine.create(function() task("A", 3) end)
local t2 = coroutine.create(function() task("B", 3) end)

-- Must explicitly schedule:
for _ = 1, 3 do
  coroutine.resume(t1)
  coroutine.resume(t2)
end
-- A1, B1, A2, B2, A3, B3 (interleaved, NOT parallel)

Status nach resume

Prüfen Sie den Status einer Coroutine, um zu entscheiden, ob Sie sie erneut fortsetzen können. Eine Coroutine, die beendet wurde (also aus ihrem Hauptteil zurückgekehrt ist), ist „dead“ – beim Fortsetzen wird false zusammen mit einem Fehler zurückgegeben. Prüfen Sie in Schleifen immer den Status, bevor Sie eine Coroutine fortsetzen.

local co = coroutine.create(function()
  for i = 1, 3 do coroutine.yield(i) end
end)

while coroutine.status(co) ~= "dead" do
  local ok, val = coroutine.resume(co)
  if ok and val ~= nil then
    print("val:", val)
  end
end
-- val: 1, val: 2, val: 3

Mehrere yield-Aufrufe in einem resume

Ein einzelner Aufruf von coroutine.resume führt die Coroutine bis zum nächsten yield oder bis zu ihrem Ende aus. Eine Coroutine kann innerhalb eines resume-Aufrufs nicht mehrfach yield aufrufen – jeder yield-Aufruf hält sie an und wartet auf den nächsten resume-Aufruf.

local co = coroutine.create(function()
  local x = coroutine.yield("first")
  print("got:", x)
  local y = coroutine.yield("second")
  print("got:", y)
end)

local _, v1 = coroutine.resume(co)         -- starts, yields "first"
print("yielded:", v1)                       -- first
local _, v2 = coroutine.resume(co, "a")   -- passes "a", yields "second"
print("yielded:", v2)                       -- second
coroutine.resume(co, "b")                   -- passes "b", coroutine ends

Schnelltest

Wozu werden die an coroutine.yield(v1, v2) übergebenen Werte?

Rückblick: resume und yield

Zusammenfassung:

  • Argumente des ersten resume-Aufrufs → Parameter des Coroutine-Hauptteils
  • Argumente nachfolgender resume-Aufrufe → Rückgabewerte des vorherigen yield()-Aufrufs
  • Argumente von yield → Rückgabewerte des resume()-Aufrufs, der yield ausgelöst hat
  • Bidirektional: Jeder resume-/yield-Aufruf ist ein Austausch
  • yield funktioniert auch aus jeder verschachtelten Funktion heraus
  • Coroutines arbeiten kooperativ, nicht parallel

Häufig gestellte Fragen

Ist die Lektion „resume und yield“ kostenlos?

Ja — der vollständige Text von „resume und yield“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Lua Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Lua Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „resume und yield“?

Tauschen Sie mit resume/yield Daten zwischen Aufrufer und Coroutine aus Du übst Lua Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um Lua Academy zu starten?

Keine Vorkenntnisse erforderlich. Lua Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 2 von 4.

Wie lange dauert die Lektion „resume und yield“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser Lua Academy-Lektion Code schreiben und ausführen?

Ja. Jede Lua Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Coroutinen erstellen
  2. resume und yield
  3. Coroutine-Status
  4. Producer-Consumer-Muster
← Zurück zu Lua Academy