[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: lua_newstate
- From: Sean Conner <sean@...>
- Date: Fri, 22 Dec 2017 18:41:42 -0500
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 ... )
[1] https://github.com/spc476/C-Coroutines
[2] Not always. On Unix, one could set up a signal handler for SIGALRM
and do the switching, but it's more involved that simple coroutines
[1].
[3] On systems with virtual memory, which is most systems today. On
systems without virtual memory, you can still have a "process" but
it's a polite fiction with some wavy hand action.