lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On Friday 04 June 2004 15:31, Wim Couwenberg wrote:
> The basic principle is to allow only a single thread
> at a time access to a particular Lua universe.  At
> least in my experience this works much nicer than
> trying to juggle with preempting OS threads on one and
> the same state.

Wim,

I know this post is few days past the subject matter. Sorry about that, but I 
let my Lua box fill to over 200 messages while being too busy in the past 
week.

After struggling to get LuaTask to compile under Linux and LynxOS a couple 
months ago, I decided to create my own preemptive threading system using 
pthreads. That's just where I'm most comfortable. My system supports passing 
of string data between threads and allows timeouts on reads. The timeouts 
work well for periodic tasks. Using the string data allows anything that can 
be stringified to be sent, and for some cases I use loadstring() to convert 
the data on the other side.

But I was considering adding exactly what you are talking about above - a 
single 'universal' Lua state that provides protected access. That limits the 
number of times that mutexes must be locked.

I'm curious about your implementation. Would you be willing to cite an example 
of two threads using your interface to the single global data? Do you have a 
single table/module in each thread that is used to hold process-global 
values? I can see how overriding __inded and __newindex would work 
beautifully for that.

For any who are interested, below is my very simple API. It is amazingly 
powerful, thanks to the designers of Lua!

function task.new(func_or_file)
-- If argument is a Lua function, copies that function to a new Lua state
-- and runs it, passing the task handle as 'self'. If it is a file, loads the
-- code in the file, then runs it after setting 'self' to the task handle.
-- Returns a task handle or nil, error message.

function task:post(s)
-- Sends the string s to the task self.
-- Returns true or nil, error message.

function task:read([timeout])
-- Waits until timeout for a message.
-- If timeout is not given, waits indefinitely.
-- timeout may be a number, in which case it specifies a duration in
-- minutes, or it may be a table of the form { sec=seconds, nsec=nanoseconds }
-- specifying the absolute time to wait until using the Posix CLOCK_REALTIME
-- clock.
-- Returns a string or nil, error message string.
-- On timeout the error string is "timeout", on thread cancellation,
-- the string is "canceled". Other errors are as strerror() reports.

I have not added a kill() function yet because I haven't needed it - it's not 
in production yet. The code uses an incrementing unsigned long to track 
instances, so even very old threads will be correctly identified as 
'canceled' on a post. The code currently creates a global table called 
'task', but that's easy enough to change.

The code is written in two layers - a C tasking model with a lua C module on 
top of it. There is no Lua native code at all. It is cleanly written and 
available to any who ask.

Doug Rogers

-- 
--__-__-____------_--_-_-_-___-___-____-_--_-___--____
Doug Rogers - ICI - V:703.893.2007x220 www.innocon.com
-_-_--_------____-_-_-___-_--___-_-___-_-_---_--_-__-_