lua-users home
lua-l archive

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




On Dec 22, 2017 5:42 PM, "Sean Conner" <sean@conman.org> wrote:
It was thus said that the Great Gregg Reynolds once stated:
> On Dec 22, 2017 12:52 PM, "Luiz Henrique de Figueiredo" <
> lhf@tecgraf.puc-rio.br> wrote:
>
> > "Creates a new thread running in a new, independent state...."
> >
> > What does "thread" mean here? A pthread, for example?
>
> "The type thread represents independent threads of execution ...
>
>
> Thanks, but I hope you can see why I find this language a little opaque.
> "Type thread represents thread" is circular.
>
> I take that the Lua engine implements it's own lthread infrastructure,
> which is non-pre-emptive. Yeah? So a Lua thread is basically a set of state
> data - an environment in which code executes. Afaik exactly parallel to any
> generic threading lib like pthreads (where a "thread" is actually a data
> structure). No? (I confess I find the language of threads confusing in
> general.)

  Lua uses coroutines, not threads (even though the Lua documentation calls
coroutines "threads").  I'll attempt to give a quick run down of the
differences, using the Intel x86-64 architecture as a concrete example
(given that it's so prevalent) and I'll start with a term I learned in
college---a "unit of execution."

  A "unit of execution" is the set of CPU registers.  The x86-64 contain a
large number of them (RAX, R15, XMM0, etc.) that are used during the
execution of a program, but the two most important ones are RIP (the
instruction pointer) and RSP (the stack pointer).  Swap out RIP and RSP (and
possibly others) and you have another "unit of execution" (as long as RIP
points to actual code, and RSP points to usable memory).

  Another term for "unit of execution" here is "coroutine."  You can see an
implementation for the x86-64 here [1].  It takes an explicit call to switch
the RIP and ESP.  These may also be called "fibers" (from Microsoft) or
"green threads" (other systems I'm blanking on). All three require explicit
action from the program to switch "units of execution."

  A "thread" is a "unit of execution" that doesn't need an explicit call to
switch execution.  Well, it does, but the "units of execution" don't need to
call the switching function.  Generally, you will have some periodic
interruption (such as a timer chip) that interrupts the current "unit of
execution."  Then this "interrupt handler" will possibly switch from the
current "unit of execution" that was running with a different one and resume
the newer one.  This "interrupt handler" is usually in the kernel and thus,
most times "threads" are managed by the kernel [2].

  A "process" is just a thread but with its own address space [3] and
definitely managed by the kernel.  But a "process" is just more than a "unit
of execution" as they are the abstraction by which system resources are
handed out---to a "process" as a whole (memory, files, etc.).  So a
"process" contains resources plus at least one "unit of execution."  There
can be many "units of execution" within a "process" but they all share the
resources of the overall "process."

  Getting back to Lua, Lua is based upon a VM, so it has its own concept of
RIP and RSP.  A call to lua_newstate() (or luaL_newstate()) returns a new
Lua VM context, which can be likened to a "process" in that it manages the
resources and contains at least one "unit of execution." The function
lua_newthread() creates a new "unit of execution" within the current Lua VM,
which the Lua documentation calls a "thread" but is more like a "coroutine"
although in any case, it's a "unit of execution" that needs to be
explicitely switched to.  And this "unit of execution" only has meaning to
the Lua VM---it is totally unrelated to the system notion of "units of
execution" (like threads or processes).

  -spc (Hope this helps some ... )

Definitely - well said! Something along these lines in PIL and/or the refman would be useful.

But now: what's the relationship between luathreads and platform threads? There is always only one lua vm, right? In my use case, lua_newstate could be called simultaneously on multiple distinct platform threads. That would work so long as the Lua engine/vm is reentrant, yes?

So my (wrapped, c) lib may call lua_newstate and then pass control to a user-defined Lua callback on multiple platform threads, in parallel. So long as the callback does not use (Lua) globals, everything should be copacetic, yes?

What if the cb needs to read/write shared data? Do it by calling a C function that handles synchronization? Use coroutines in some way?

Thanks, 
G