Lua real multithreading using Lanes and Linda


In this post I’ll share my first impression and thoughts about developing mulithreaded applications in lua.
When developing in lua you may have realized that there is no such thing as multithreading, but there is a concept that is propposed as an alternative, called coroutines, which is useful for developing single-threaded applications and sharing the processor between several routines.
Coroutines may be the desired approach for several programs, but sometimes real multithreading is required, as in the case of 2 routines that must execute simultaneously and at a different frequency or when you need a thread to block waiting for user input while doing some background processing. There are lots of examples about this, but I think I made my point.
In my case I wanted to implement a keyboard controlled wheeled robot, so I needed 2 threads, one that would block waiting for user input (arrow keys), and another which would use the input values to control my robot.


In order to develop the keyboard controlled robot I found a multithreading library for lua called Lua Lanes (you can find more information in the LuaLanes github project), which allows running multiple lua states in parallel.
Installing Lua Lanes is very easy, just run from the terminal:

luarocks install lanes

After installing I tried the lua scripts proposed as examples in the page, but for my surprise, they didn’t work!
I am using lua version 5.1 and Lua Lanes dated december 2010, and in my case, looking at examples and by trial and error I got to a very simple and working example, which runs 2 functions in parallel, here is the script:

–import extension and initialize
lanes = require "lanes".configure()

–thread 1 function
local function loop1( )
while true do
os.execute("sleep 0.1")

–thread 2 function
function loop2()
while true do
os.execute("sleep 0.1")

–create and start the threads, notice the ‘()’ to start the thread. you can parameters to the function.
thread1= lanes.gen("*",loop1)()
thread2= lanes.gen("*",loop2)()

This script works fine for me, it should work also for you. You could even define each loop in different lua files, decoupling the function from the threads script.


After successfully running lua lanes, the only thing left is to pass data from one lane (thread) to another. The api to do this is called Linda, which offers two ways of sending data between lanes:

  • Data queue, as a producer/consumer way (send/receive functions)
  • Single Data slot, which is overriden every time it’s written to (set/get functions)

There is some example using send and receive functions in the lanes documentation, and here is a working example using set and get.

lanes = require "lanes".configure()

local linda= lanes.linda()

local function loop( )
for i=1,10 do
print( "sending: "..i )
linda:set( "x", i )
print("end sender")

function receiver()
while true do
local val= linda:get( "x" )
if val==nil then
print( "nil received" )
print( "received: "..val )

print("end receiver")

a= lanes.gen("*",loop)()
b= lanes.gen("*",receiver)()

Conclusions and considerations

Lanes and Lindas are a nice alternative to multithreading in lua, since there are no built in functionality to do this.
It may be seem not trivial to configure it at the beginning, but once you have a working example it works fine.
Last but not least, it’s not trivial to find errors on a specific lane; in case one lane stops running due to a failed assertion or some other error, that lane won’t print an error to the console and will stop running. This can be avoided by not using assert, printing errors and exit the program in case an error is detected to signal other lanes to stop.


Simon says game in BeagleBoard SBC


In my last post about GPIO and LEDs in lua I wrote about a nice feature in Linux when working on embedded systems, such as the possibility to access hardware devices using the file system.
In this post I’ll be using this feature to build the game ‘Simon says’ in lua. I’ll be using a BeagleBoard rev C4 with ubuntu 11.04 installed.
We made this project with my colleagues for an embedded robotics course, so the credit is also shared with them 🙂

GPIOs in the Beagleboard Note

According to the Beagleboard datasheet, the processor can be configured to use all the pins in the expansion port as GPIOs, but this is a more advanced task which requires changing the MUX registers in the processor, which can be achieved by recompiling the kernel changing the kernel headers.
The Ubuntu image for Beagleboard already has several pins configured as GPIO. Thanks to Michael Shiloh, he found the pins that can be used as GPIO by default. This is the list of GPIOs you can use (and the corresponding pin in the expansion port):

  • 157 (pin 22)
  • 159 (pin 18)
  • 161 (pin 16)
  • 162 (pin 14)
  • 136 (pin 9)
  • 137 (pin 7)
  • 138 (pin 5)
  • 139 (pin 3)

For a reference on the pin number for each of these GPIOs read the Beagleboard datasheet.


For this game I only used 3 LEDS, because at that time I didn’t have more of these 🙂 but it’s very easy to add more.
I used 3 GPIO ports to connect the LEDs and 3 for the buttons. Using the default ubuntu installation I could plug 4 leds and 4 buttons. If I wanted more, I should tune the kernel as said earlier in the post.

Connecting the leds and buttons

The picture below shows how everything is connected. It works as a proof of concept, but I wouldn’t give this to anyone to play 😛

Since the picture does not explain this clearly
I used pins 3,5,7 (GPIO 139,138,137 respectively) as input for the buttons and pins 12,14,16 (GPIO 158,162,161 respectively) as output GPIOs for the LEDs.
The diagram below shows how to connect the buttons and leds.

Source code

The source code is available in Github
The source code is quite simple, The GPIO library explained in the GPIO post was used to interface with the leds and buttons.
The rest of the code is just a main loop implementing the game logic. When the user loses, the leds blink several times and the application quits.

That’s it for now. Let me know if you have any comments or if the code was any use for you! Please share! 😀