Lua Coroutines
A coroutine is a function that can pause in the middle and continue later from the same place. The main program decides when the coroutine runs and when it pauses.
A producer yields 10, then 20
producer yields 10 on the first resume and 20 on the second. Each resume stores the yielded value in v, and the prints show 10 then 20.
local function producer()
coroutine.yield(10)
coroutine.yield(20)
end
local co = coroutine.create(producer)
local ok, v = coroutine.resume(co)
print(v)
ok, v = coroutine.resume(co)
print(v)Status goes from suspended to dead
steps yields once and then ends. The status prints suspended before any resume and dead after the second resume runs it to the end.
local function steps()
coroutine.yield(1)
end
local co = coroutine.create(steps)
print(coroutine.status(co))
coroutine.resume(co)
coroutine.resume(co)
print(coroutine.status(co))Main and coroutine take turns
The greeting coroutine prints one line, yields, and waits. The main line prints in between, and that order proves the coroutine paused.
local function greeter()
print("Hello from inside")
coroutine.yield()
print("Back inside again")
end
local co = coroutine.create(greeter)
print("Start")
coroutine.resume(co)
print("Main pauses it here")
coroutine.resume(co)
print("Done")Example
local function progress()
coroutine.yield(25)
coroutine.yield(50)
coroutine.yield(75)
coroutine.yield(100)
end
local co = coroutine.create(progress)
while coroutine.status(co) ~= "dead" do
local ok, v = coroutine.resume(co)
if v then
print("Progress: " .. v .. "%")
end
end
print("Done")Key points
- Create: coroutine.create(f) wraps a function and returns a coroutine that has not started yet.
- Resume: coroutine.resume(co) starts a coroutine or continues it from its last pause.
- Yield: coroutine.yield(v) pauses the coroutine and hands the value v back to the resume call.
- Resume result: a successful resume returns true plus the yielded value.
- Status: coroutine.status(co) returns "suspended" while a coroutine can still continue.
- Dead: coroutine.status(co) returns "dead" after the coroutine function has finished.
In this example, progress yields 25, 50, 75, and 100, one value per resume. The while loop keeps resuming while the status is not dead, prints one progress line for each yielded value, and prints Done after the fifth resume ends the coroutine.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
What happens when a running coroutine reaches coroutine.yield(30)?