🎓 A1Learner
🔍
0 of 52 lessons completed

Lua Producer Consumer Coroutines

A producer consumer pair is a coroutine that makes values and a caller that takes them one at a time. Each resume asks for the next value and each yield hands one value back.

A producer hands out one value per resume

The producer yields three numbers and then ends. Four resumes take each value in turn.

local producer = coroutine.create(function()
  coroutine.yield(10)
  coroutine.yield(20)
  coroutine.yield(30)
end)
local ok, value = coroutine.resume(producer)
print(ok, value)
local ok2, value2 = coroutine.resume(producer)
print(ok2, value2)
local ok3, value3 = coroutine.resume(producer)
print(ok3, value3)
local ok4 = coroutine.resume(producer)
print(ok4)

Values can travel in both directions

The producer first yields the word ready. The next resume sends 5 and the producer yields 15.

local co = coroutine.create(function()
  local got = coroutine.yield("ready")
  coroutine.yield(got + 10)
end)
local ok, value = coroutine.resume(co)
print(ok, value)
local ok2, value2 = coroutine.resume(co, 5)
print(ok2, value2)

A loop can take every value until the producer ends

The loop resumes while the producer is not dead. It prints each yielded square and stops at the end.

local co = coroutine.create(function()
  for i = 1, 3 do
    coroutine.yield(i * i)
  end
end)
while coroutine.status(co) ~= "dead" do
  local ok, value = coroutine.resume(co)
  if value then
    print(value)
  end
end

Example

local producer = coroutine.create(function()
  local step = coroutine.yield("start")
  for n = 1, 3 do
    coroutine.yield(n * step)
  end
  return "done"
end)
local ok, value = coroutine.resume(producer)
print(ok, value)
local ok2, value2 = coroutine.resume(producer, 10)
print(ok2, value2)
local ok3, value3 = coroutine.resume(producer)
print(ok3, value3)
local ok4, value4 = coroutine.resume(producer)
print(ok4, value4)
local ok5, value5 = coroutine.resume(producer)
print(ok5, value5)

Key points

  • Producer: the producer is the coroutine body that yields each value in turn.
  • Consumer: the consumer is the caller that resumes the coroutine to get each value.
  • Yield: yield pauses the producer and hands a value to the consumer.
  • Send: a value passed to resume becomes the result of yield inside the producer.
  • Return: the last resume returns true plus the return value when the producer finishes.

In this example, the first resume starts the producer and takes the word start. The second resume sends 10 as the step and takes the first product. Later resumes take 20 and 30, and the last resume takes the return word done.

Note

the consumer checks the first resume result before it uses a yielded value.

Try it Yourself

Edit the code, then press Run.

Running is simulated

Exercise

The producer yields a value and waits. What does the next resume argument become inside the producer?