Lua - Coroutine Life Cycle



A coroutine life cycle is a set of states from creation of co-rountine, its running till end of it. Lua provides couple of methods to control the life cycle of a coroutine. Following are the methods which play roles in a corountine life cycle.

  • coroutine.create() − creates a coroutine.

  • coroutine.resume() − starts a coroutine.

  • coroutine.yield() − pauses a coroutine execution.

  • return − return statements ends the coroutine execution.

Let's explore each state with examples.

Example - Create a coroutine

We can create a co-routine using corountine.create() function. At this time, the coroutine is in suspended state and it is not started.

main.lua

-- create a function to track coroutines
function main()
   local function helper()
      -- create a coroutine
      co = coroutine.create(function ()
         print("Coroutine started")
         coroutine.yield()
         print("Coroutine resumed")
      end)
      return co
   end
      print("Main: Resuming coroutine")
   local status, value = coroutine.resume(helper())
   print("Main: Coroutine yielded with status:", status, "and value:", value) -- status will be true, value will be nil (no argument to yield)
end

main()

Running program will not be doing any thing as corountine is just created and is currently in suspended state.

Example - Starting and Yielding a coroutine

We can use corountine.resume() function to start a coroutine. In case, coroutine.yield(), current coroutine execution stops and control is returned back to the caller function. When we passed an argument to corountine.yield(), it is returned by corountine.resume() call.

main.lua

-- create a function to track coroutines
function main()
   local function helper()
      -- create a coroutine
      co = coroutine.create(function ()
         print("Coroutine started")
         coroutine.yield(1) -- yield coroutine by 1
         print("Coroutine resumed")
      end)
      return co
   end
   print("Main: Coroutine resumed.")
   local status, value = coroutine.resume(helper())
   print("Main: Coroutine yielded with status:", status, "and value:", value)
end
main()

Output

When we run the above program, we will get the following output−

Main: Coroutine resumed.
Coroutine started
Main: Coroutine yielded with status:	true	and value:	1

Example - Starting and Yielding a coroutine

We can use corountine.resume() function to start a coroutine. In case, coroutine.yield(), current coroutine execution stops and control is returned back to the caller function. When we passed an argument to corountine.yield(), it is returned by corountine.resume() call.

main.lua

-- create a function to track coroutines
function main()
   local function helper()
      -- create a coroutine
      co = coroutine.create(function ()
         print("Coroutine started")
         coroutine.yield() -- yield coroutine
         print("Coroutine resumed")
      end)
      return co
   end
   print("Main: Coroutine resumed.")
   local status, value = coroutine.resume(helper())
   print("Main: Coroutine yielded with status:", status, "and value:", value)
end
main()

Output

When we run the above program, we will get the following output−

Main: Coroutine resumed.
Coroutine started
Main: Coroutine yielded with status:	true	and value:	nil

Example - Resuming a coroutine

We can use corountine.resume() function to resume a coroutine from where coroutine yielded.

main.lua

-- create a function to track coroutines
function main()
   local function helper()
      -- create a coroutine
      co = coroutine.create(function ()
         print("Coroutine started")
         coroutine.yield(1) -- yield coroutine by 1
         print("Coroutine resumed")
      end)
      return co
   end
   print("Main: Coroutine resumed.")
   local status, value = coroutine.resume(helper())
   print("Main: Coroutine yielded with status:", status, "and value:", value)
end
main()

Output

When we run the above program, we will get the following output−

Main: Coroutine resumed.
Coroutine started
Main: Coroutine yielded with status:	true	and value:	1

Example - Completion of a coroutine

When we return a value from a coroutine, it terminates and marks the completion of the coroutine. Once completed, a coroutine cannot be resumed.

main.lua

co = coroutine.create(function ()
   print("Coroutine started.")
   return "Coroutine finished."
end)

local status, value = coroutine.resume(co)
print("Main: Coroutine finished with status:", status, "and value:", value)

local status, err = coroutine.resume(co)
print("Main: Attempting to resume finished coroutine with status:", status, "and value:", err)

Output

When we run the above program, we will get the following output−

Coroutine started.
Main: Coroutine finished with status:	true	and value:	Coroutine finished.
Main: Attempting to resume finished coroutine with status:	false	and value:	cannot resume dead coroutine

Summary

Following states represents the lifecyle of a coroutine.

  • Running− refers that coroutine is currently executing.

  • Suspended− refers that a coroutine is either not started or suspended using yield() method.

  • Completed− refers that coroutine has finished its execution and cannot be resumed.

Advertisements