Skip to content
This repository has been archived by the owner on Jun 27, 2020. It is now read-only.

Considerations

ColonelThirtyTwo edited this page Mar 12, 2013 · 1 revision

One of the goals I had in writing LuaJIT-Threads was to make it as easy and straightforward as possible. Unfortunately, as Lua is not made to support threading, there are a few specific things to be aware of, aside from the usual considerations for threaded programs (synchronization, etc).

Threads are Separated

The first thing to note is that each thread has its own lua_State object; they don't share anything with each other. This includes packages loaded with require, cdefs, and upvalues of the thread main function (which are reset to nil by string.dump).

For example, consider this code:

local Threading = require "threads"
local mylib = require "mylib"

local t = Threading.Thread(function()
	mylib.doSomething() -- ERROR!
end)
assert(t:join())
t:destroy()

This code will throw an error on line 5 saying mylib is nil, because it is an upvalue. The correct code is:

local Threading = require "threads"
local mylib = require "mylib"

local t = Threading.Thread(function()
	local mylib = require "mylib" -- Require it again in the spawned thread
	mylib.doSomething() -- Now we can use it!
end)
assert(t:join())
t:destroy()

Cdata Conversions

Due to limitations with LuaJIT's C API, cdata ojbects passed as arguments to the thread's main function are converted into lightuserdata objects when passed into the thread. Thus, before the thread can actually use the objects, it has to cast it.

For example:

local Threading = require "threads"
local ffi = require "ffi"

local result = ffi.new("int[1]")
local t = Threading.Thread(function(r, a, b)
	local ffi = require "ffi" -- Don't forget to import ffi into the thread!
	r = ffi.cast("int*",r) -- Recast the lightuserdata into a cdata pointer
	r[0] = a + b
end, result, 1, 2)
assert(t:join())
t:destroy()
print(result[0])
Clone this wiki locally