Semaphore Library
The Semaphore library provides some core-level synchronisation tools for tasks.
This example shows how to use a counting semaphore to efficiently keep a thread asleep, but to wake it immediately when there's work to do.
jobs = {}
jobs.q = {}
jobs.r = {} -- results
jobs.sem = semaphore.new()
function jobs.Thread(this_thread, this_name)
while this_thread:run()
do
if jobs.sem:wait(500) -- wait for the semaphore
then
-- do work
local te = table.remove(jobs.q, 1)
if te and (type(te.func) == 'function')
then
local res = {te.func(unpack(te.args))}
if #res > 0
then
local re = {} -- result entry
re.res = res
re.func = te.func
re.args = te.args
table.insert(jobs.r, re)
end
end
else
-- do some housekeeping on the timeout
end
end
end
function jobs.Add(func, ...)
local te = {}
te.func = func
te.args = {...}
table.insert(jobs.q, te)
jobs.sem:release() -- wake up the thread immediately
end
the_thread = thread.new(jobs.Thread, 'JobThread')
jobs.Add(TestFunction, {'Hello', 1,2,3}) -- add a job
This example doesn't save the function results.
Code each function to store results before it exits.
jobs = jobq.new()
jobs.sem = semaphore.new()
function jobs.Thread(this_thread, this_name)
while this_thread:run()
do
if jobs.sem:wait(500) -- wait for the semaphore
then
jobs.sem:clear() -- reset the count, we are on it!
jobs:run() -- run all pending jobs in the queue
else
-- do some housekeeping on the timeout
end
end
end
-- Note: this overwrites the default jobq.add definition for `jobs`
function jobs.add(jq, func, ...)
jobq.add(jq, func, {...}, true)
jq.sem:release() -- wake up the thread immediately
end
the_thread = thread.new(jobs.Thread, 'JobThread')
…
jobs:add(TestFunction, 'Hello', 1,2,3) -- add a job (note the `:`!)
Because the jobq
object is just a pure Lua table, with metamethods, we can add the semaphore, and the named entries (add
and Thread
).