Coroutines

23.1 Basics

Create a coroutine (a thread) coroutine.resume(co,...) Start/continue; returns true, values... or false, error

Suspend; values go to resume's results "suspended", "running", "normal", "dead"

Returns a function that resumes (errors propagate) Can the running code yield?

Current coroutine (+ ismain flag in 5.2+) Close a suspended/dead coroutine, running pending <close> variables (5.4)

local co = coroutine.create(function(a, b)
    print("start", a, b)
    local c = coroutine.yield(a + b)       -- suspend, passing a value out
    print("resumed with", c)
    local d, e = coroutine.yield(c * 2)
    print("resumed with", d, e)
    return "finished"
end)

print(coroutine.status(co))               --> suspended
print(coroutine.resume(co, 1, 2))         --> start 1 2   then: true 3
print(coroutine.resume(co, 10))           --> resumed with 10  then: true 20
print(coroutine.resume(co, "x", "y"))     --> resumed with x y  then: true finished
print(coroutine.status(co))               --> dead
print(coroutine.resume(co))               --> false  cannot resume dead coroutine

23.2 Key Properties

Lua coroutines are asymmetric (yield returns to whoever resumed), stackful (you can yield from nested function calls), and cooperative (they don't run in parallel; there's no preemption).

They're cheap (about 1 KB each), so you can create thousands.

Yield across C boundaries: 5.2+ supports yielding through pcall, metamethods, and iterators (via continuations in the C API). Lua 5.1 can't yield across pcall (LuaJIT can).