0Pricing
Lua Academy · Lektion

Coroutine-Status

Prüfen Sie den Zustand einer Coroutine mit coroutine.status: running, suspended, dead

Coroutine-Status ist eine kostenlose Lua Academy-Lektion auf CoddyKit. Dies ist Lektion 3 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.

Vier Coroutine-Zustände

Coroutines können sich in vier Zuständen befinden: suspended (erstellt oder durch yield angehalten und wartet auf die Ausführung), running (wird gerade ausgeführt), normal (angehalten, damit eine andere Coroutine ausgeführt werden kann) und dead (beendet oder mit einem Fehler abgebrochen). Fragen Sie den Zustand mit coroutine.status(co) ab.

local co = coroutine.create(function()
  print(coroutine.status(coroutine.running()))  -- running
  coroutine.yield()
end)

print(coroutine.status(co))  -- suspended
coroutine.resume(co)          -- prints: running
print(coroutine.status(co))  -- suspended
coroutine.resume(co)
print(coroutine.status(co))  -- dead

Der Zustand „normal“

Eine Coroutine wechselt in den Zustand „normal“, wenn sie eine andere Coroutine fortsetzt. Sie wird nicht ausgeführt (das übernimmt die andere Coroutine), ist aber auch nicht angehalten – sie wartet darauf, dass die fortgesetzte Coroutine yield aufruft. Dieser Zustand tritt selten auf, ist aber für das Verständnis komplexer Coroutine-Strukturen wichtig.

local inner, outer

inner = coroutine.create(function()
  print("outer status:", coroutine.status(outer))  -- normal
  coroutine.yield()
end)

outer = coroutine.create(function()
  coroutine.resume(inner)
end)

coroutine.resume(outer)
-- prints: outer status: normal

Vor dem Fortsetzen prüfen

Prüfen Sie immer den Status einer Coroutine, bevor Sie sie fortsetzen, insbesondere in Schleifen. Das Fortsetzen einer beendeten Coroutine ist ein Fehler. Auch das Fortsetzen einer laufenden Coroutine ist ein Fehler, da dies zu unendlicher Rekursion führen würde.

local function safeResume(co, ...)
  local status = coroutine.status(co)
  if status == "dead" then
    return false, "cannot resume dead coroutine"
  end
  if status == "running" then
    return false, "cannot resume running coroutine"
  end
  return coroutine.resume(co, ...)
end

Status nach einem Fehler

Wenn der Hauptteil einer Coroutine einen nicht abgefangenen Fehler auslöst, gibt coroutine.resume false und die Fehlermeldung zurück. Die Coroutine wechselt in den Zustand „dead“. Sie kann nicht neu gestartet werden – wenn Sie den Vorgang wiederholen möchten, müssen Sie eine neue Coroutine erstellen.

local co = coroutine.create(function()
  error("something went wrong")
end)

local ok, err = coroutine.resume(co)
print(ok, err)                      -- false  ...: something went wrong
print(coroutine.status(co))         -- dead

-- Cannot resume dead coroutine:
local ok2, err2 = coroutine.resume(co)
print(ok2, err2)  -- false  cannot resume dead coroutine

coroutine.isyieldable

coroutine.isyieldable() gibt true zurück, wenn die laufende Coroutine yield aufrufen kann. Im Haupt-Thread und in C-Funktionen, die yield nicht unterstützen, wird false zurückgegeben. Prüfen Sie den Kontext immer, bevor Sie yield aufrufen, wenn Sie sich über ihn nicht sicher sind.

local co = coroutine.create(function()
  print("isyieldable:", coroutine.isyieldable())  -- true
  coroutine.yield()
end)

coroutine.resume(co)

-- In main thread:
print("isyieldable:", coroutine.isyieldable())  -- false
-- coroutine.yield()  -- ERROR in main thread

Eine Gruppe von Coroutines überwachen

Verwalten Sie einen Pool von Coroutines und entfernen Sie nach jeder Runde von resume-Aufrufen die beendeten Coroutines. Dies bildet die Grundlage eines Task-Schedulers.

local function makeWorker(n, name)
  return coroutine.create(function()
    for i = 1, n do
      print(name, "step", i)
      coroutine.yield()
    end
  end)
end

local workers = {
  makeWorker(2, "fast"),
  makeWorker(4, "slow"),
}

while #workers > 0 do
  local alive = {}
  for _, co in ipairs(workers) do
    coroutine.resume(co)
    if coroutine.status(co) ~= "dead" then
      alive[#alive+1] = co
    end
  end
  workers = alive
end

Coroutines debuggen

Verwenden Sie Statusprüfungen, um Coroutine-basierten Code zu instrumentieren und zu debuggen. Geben Sie Statusänderungen aus, um den Ablauf zu verstehen. Weisen Sie Coroutines in komplexen Systemen über eine Wrapper-Tabelle Namen zu, damit die Debugging-Ausgabe aussagekräftiger wird.

local function namedCo(name, fn)
  local co = coroutine.create(fn)
  return {
    co = co,
    name = name,
    resume = function(self, ...)
      print("[" .. self.name .. "] resume")
      local results = table.pack(coroutine.resume(self.co, ...))
      print("[" .. self.name .. "] status: " .. coroutine.status(self.co))
      return table.unpack(results, 1, results.n)
    end
  }
end

local worker = namedCo("worker1", function()
  coroutine.yield()
end)
worker:resume()
worker:resume()

Beendete Coroutines neu starten

Sobald eine Coroutine den Zustand „dead“ erreicht hat, kann sie nicht fortgesetzt werden. Um sie „neu zu starten“, müssen Sie aus derselben Funktion eine neue Coroutine erstellen. Ein gängiges Muster ist eine Factory, die bei Bedarf eine neue Coroutine erstellt.

local function makeCounter(start, step)
  return coroutine.wrap(function()
    local n = start or 0
    while true do
      coroutine.yield(n)
      n = n + (step or 1)
    end
  end)
end

local count = makeCounter(0, 2)
for i = 1, 5 do io.write(count() .. " ") end
print()  -- 0 2 4 6 8

-- "Restart" by creating a new one
count = makeCounter(100)
print(count())   -- 100

Fehlerverhalten von Coroutine.wrap

Wenn eine umschlossene Coroutine einen Fehler verursacht, wird dieser aus dem Aufruf der Wrapper-Funktion heraus weitergegeben. Anders als coroutine.resume, das false und einen Fehler zurückgibt, lösen von wrap zurückgegebene Funktionen den Fehler direkt aus. Verwenden Sie pcall um wrap-Aufrufe herum, wenn Sie Fehler abfangen müssen.

local gen = coroutine.wrap(function()
  coroutine.yield(1)
  error("oops")
  coroutine.yield(2)  -- never reached
end)

print(gen())   -- 1 (ok)
local ok, err = pcall(gen)
print(ok, err) -- false  ...: oops
-- Subsequent call: dead coroutine
ok, err = pcall(gen)
print(ok, err) -- false  cannot resume dead coroutine

isyieldable im Vergleich zu status

Es gibt zwei Möglichkeiten, den Coroutine-Kontext zu untersuchen: coroutine.status(co) liefert den Zustand einer bestimmten Coroutine; coroutine.isyieldable() gibt an, ob der aktuelle Ausführungskontext yield aufrufen kann. Verwenden Sie status, um andere Coroutines zu prüfen, und isyieldable, um festzustellen, ob Sie sicher yield aufrufen können.

local function maybeYield()
  if coroutine.isyieldable() then
    coroutine.yield()
  else
    -- in main thread or non-yieldable context
    print("cannot yield here")
  end
end

maybeYield()  -- prints "cannot yield here" (main thread)

local co = coroutine.create(maybeYield)
coroutine.resume(co)   -- yields successfully

Schnelltest

In welchen Zustand wechselt eine Coroutine, wenn sie die Ausführung ihrer Hauptfunktion beendet?

Rückblick: Coroutine-Status

Zusammenfassung:

  • Zustände: suspended → running ↔ normal → dead
  • coroutine.status(co) gibt die Zustandszeichenkette zurück
  • Dead bedeutet beendet oder fehlerhaft; die Coroutine kann nicht fortgesetzt werden
  • coroutine.isyieldable() prüft, ob der aktuelle Kontext yield aufrufen kann
  • Prüfen Sie in Schleifen immer den Status, bevor Sie eine Coroutine fortsetzen
  • Fehler von wrap werden direkt weitergegeben; resume gibt false+err zurück

Häufig gestellte Fragen

Ist die Lektion „Coroutine-Status“ kostenlos?

Ja — der vollständige Text von „Coroutine-Status“ 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 „Coroutine-Status“?

Prüfen Sie den Zustand einer Coroutine mit coroutine.status: running, suspended, dead 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 3 von 4.

Wie lange dauert die Lektion „Coroutine-Status“?

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