Say, I have a lua table t={"a"={}, "b"={}}.
My question is, I have two threads, thread A, thread B.
And if I create two lua_State individually for these two threads through lua_newthread, and thread A only read/write t.a, thread B only read/write t.b.
Should I use lua_lock in each thread above?
If the answer is YES, then, does any of operation on t need a lua_lock?
TL;DR: A Lua engine-state is not thread-safe, so there's no reason to make the Lua table thread-safe.
A lua_State is not the engine state, though it references it. Instead, it is the state of a Lua thread, which is no relation to an application thread. Lua threads with the same engine state cannot execute concurrently, as the Lua engine is inherently single-threaded (you may use an arbitrary number of engines at the same time though), instead they are cooperatively multitasked.
So lua_State *lua_newthread (lua_State *L); creates a new Lua thread, not an OS thread.
lua_lock and the like do not refer to thread safety, but were the way native code can keep hold of Lua objects across calls into the engine in version 2 of the implementation: https://www.lua.org/manual/2.1/subsection3_5_6.html
The modern way is using the registry, a Lua table accessible from native code: http://www.lua.org/manual/5.3/manual.html#4.5
lua table isn't thread safe, but there's no need to lock since threads don't read/write on the same element.
NO, lua table is not thread safe.
And yes, all operation on table t will need lua_lock, because none of them is atomic operation.
Related
My application uses Lua in multithreaded environment with global mutex. It implemented like this:
Thread locks mutex,
Call lua_newthread
Perform some initialization on coroutine
Run lua_resume on coroutine
Unlocks mutex
lua_lock/unlock is not implemented, GC is stopped, when lua works with coroutine.
My question is, can I perform steps 2 and 3 without locking, if initialisation process does not requires any global Lua structs? Can i perform all this process without locking at all, if coroutine does not requires globals too?
In what case I generally can use Lua functions without locking?
Lua does not guarantee thread safety if you're trying to use single Lua state in separate OS threads without lua_lock/unlock. If you want to use multithreaded environment you need to use individual state for each OS thread.
Look at some multithreading solutions, e.g. https://github.com/effil/effil.
In what case I generally can use Lua functions without locking?
On the same Lua state (or threads derived from the same source Lua state)?
None.
Lua is thread-safe in the sense that separate Lua state instances can be executed in parallel. There are absolutely no thread safety guarantees when you call any Lua API function from two different threads on the same Lua state instance.
You cannot do any of the steps 2, 3, or 4 outside of some synchronization mechanism to prevent concurrent access to the same state. It doesn't matter if it's just creating a new thread (which allocates memory) or some "initialization process" (which will likely allocate memory). Even things that don't allocate memory are still not allowed.
Lua offers no guarantees about thread-safety within a Lua state.
Let's say that I have a shared object that has a piece of code protected with a critical section and more than 1 thread are accessing the object for read/write. When a thread is inside the critical section the other threads are waiting. Once the thread gets out of the CS then the OS gives access to any of the waiting threads.
If I am confined to only one process, does the CS alone is a good protection for the shared object?
I ask because I have seen on the web that the right way to do it is to use a kernel object (ex: mutex, semaphone) to guard the CS. A thread wishing to use the shared resource needs to obtain the mutex/semaphore first with a WaitForSingleObject type of function. If a mutex is used then only one of then can access the resource. Once the mutex is obtained then the thread Enters the CS, does what is supposed to do, then Leave the CS and Releases the mutex. Then the OS allows any other waiting thread to obtain the mutex and so on and so forth.
But isn't is the same as using only the CS?
Also, using a mutex is supposed to be significantly slower than using a CS alone. The only problem I see of using only a CS is that if the thread crashes inside the CS then the other threads may never access the shared resource.
Is there any other reason why this approach is better?
thanks in advance
It sounds like you're discussing some Windows-specific terminology in a way that's getting it mixed up with some general computer science terminology.
In computer science the term "critical section" is used for areas of code that must run exclusively (usually due to data sharing). In Windows, there's a synchronization object called CRITICAL_SECTION that can be used to provide exclusive access to areas of execution. Another attribute of a CRITICAL_SECTION object on Windows is that it is limited to being used within a single process.
In computer science, the term 'mutex' is often used to describe an object that can be used to provide synchronization among parallel or cncurrent threads of execution. In Windows, there is also a mutex object which can be created with the CreateMutex() function (which returns a HANDLE representing the mutex). That object can be used to synchronize access among threads in the same or different processes, so it can be used similar to a CRITICAL_SECTION (but with different APIs) in many ways. If you want to synchronized threads of execution that are in different processes, a mutex object can be used, while a CRITICAL_SECTION object cannot.
So to answer your question (I think), if you are only concerned with protecting a critical section among threads that are part of the same process, a CRITICAL_SECTION object should be adequate. A mutex object can be used instead, but it may be somewhat less performant. There should be no need to use both types of objects
I haven't been able to write a program in Lua that will load more than one CPU. Since Lua supports the concept via coroutines, I believe it's achievable.
Reason for me failing can be one of:
It's not possible in Lua
I'm not able to write it ☺ (and I hope it's the case )
Can someone more experienced (I discovered Lua two weeks ago) point me in right direction?
The point is to write a number-crunching script that does hi-load on ALL cores...
For demonstrative purposes of power of Lua.
Thanks...
Lua coroutines are not the same thing as threads in the operating system sense.
OS threads are preemptive. That means that they will run at arbitrary times, stealing timeslices as dictated by the OS. They will run on different processors if they are available. And they can run at the same time where possible.
Lua coroutines do not do this. Coroutines may have the type "thread", but there can only ever be a single coroutine active at once. A coroutine will run until the coroutine itself decides to stop running by issuing a coroutine.yield command. And once it yields, it will not run again until another routine issues a coroutine.resume command to that particular coroutine.
Lua coroutines provide cooperative multithreading, which is why they are called coroutines. They cooperate with each other. Only one thing runs at a time, and you only switch tasks when the tasks explicitly say to do so.
You might think that you could just create OS threads, create some coroutines in Lua, and then just resume each one in a different OS thread. This would work so long as each OS thread was executing code in a different Lua instance. The Lua API is reentrant; you are allowed to call into it from different OS threads, but only if are calling from different Lua instances. If you try to multithread through the same Lua instance, Lua will likely do unpleasant things.
All of the Lua threading modules that exist create alternate Lua instances for each thread. Lua-lltreads just makes an entirely new Lua instance for each thread; there is no API for thread-to-thread communication outside of copying parameters passed to the new thread. LuaLanes does provide some cross-connecting code.
It is not possible with the core Lua libraries (if you don't count creating multiple processes and communicating via input/output), but I think there are Lua bindings for different threading libraries out there.
The answer from jpjacobs to one of the related questions links to LuaLanes, which seems to be a multi-threading library. (I have no experience, though.)
If you embed Lua in an application, you will usually want to have the multithreading somehow linked to your applications multithreading.
In addition to LuaLanes, take a look at llthreads
In addition to already suggested LuaLanes, llthreads and other stuff mentioned here, there is a simpler way.
If you're on POSIX system, try doing it in old-fashioned way with posix.fork() (from luaposix). You know, split the task to batches, fork the same number of processes as the number of cores, crunch the numbers, collate results.
Also, make sure that you're using LuaJIT 2 to get the max speed.
It's very easy just create multiple Lua interpreters and run lua programs inside all of them.
Lua multithreading is a shared nothing model. If you need to exchange data you must serialize the data into strings and pass them from one interpreter to the other with either a c extension or sockets or any kind of IPC.
Serializing data via IPC-like transport mechanisms is not the only way to share data across threads.
If you're programming in an object-oriented language like C++ then it's quite possible for multiple threads to access shared objects across threads via object pointers, it's just not safe to do so, unless you provide some kind of guarantee that no two threads will attempt to simultaneously read and write to the same data.
There are many options for how you might do that, lock-free and wait-free mechanisms are becoming increasingly popular.
I have a program with 4 threads.
Within each thread, I do a luaL_newstate();
Each thread only has access to it's own lua instance.
Is there anything I need to worry about? [I.e. is there some hidden state that all lua instances share behind my back?]
Thanks!
No, that should work just fine. All interpreter state is self contained in each Lua instance. I would even say that is the preferred way to use Lua with multiple threads and/or processes.
If you find that you do need to communicate between Lua states eventually, then it is best to serialize the data and pass it using the C API. I recommend reading the "Exploring Lua for Concurrent Programming" whitepaper. It introduces a method of using multiple Lua processes with message passing for inter-process communication.
Creating a single lua_State per thread is a good solution to having multiple threads of Lua execution. However, those states are very separated. In particular, it is difficult to safely communicate between them since the Lua API is only thread-safe as long as each lua_State is accessed from a single thread at a time. (Well, unless lua_lock and lua_unlock are implemented as a suitable mutex, which they are not in the default builds of the lua core.)
If that level of isolation is not acceptable, then you need to investigate one of the several mechanisms for allowing Lua instances to play well with others in a threaded process.
My favorite choice is Lua Lanes which provides for multiple threads along with a mechanism for passing messages and sharing values between them in a thread-safe way. Values of most Lua types (including userdata with a little C side support from the library that uses it) can be safely and efficiently passed from one lane to another.
Other mechanisms exist, and a good starting point for most of them is at the Lua user's wiki page on MultiTaksing.
You're good as long as you don't try to pass values between Lua instances without converting them to C first. For example, it will be nearly impossible to share a mutable table among instances.
What you ask sounds easy to do but not necessarily any more useful than simply having multiple processes running, each with its own Lua and its own address space.
I was wondering whether it would ever make sense to use a mutex or semaphore when there is only one thread?.
Thanks for your help.
I design thread protection into my components because they are reusable and scalable components intended to work in any environment I can realistically anticipate. Many times they are initially used in a single thread environment. Often times the scope of the implementation expands to include more threads. Then I don't have to chase down resources to protect from the new access scenarios.
Mutex can make sense, since Mutex can be used for system wide sharing, instead of internal process-wide sharing. For example, you can use a Mutex to prevent an application from being started twice.
This may be a bit out there but lets say you are writing a recursive function and you want each level to register with a separate resource. This way you can keep the responsibility of cleaning up the resource in one place (The resource pool).
Sounds like a trick question. Technically, yes. A named mutex can be used to synch multiple processes containing a single thread in each.
You can use system-wide semaphores (and even mutexes) to do inter-process communication.
You can signal from a single-threaded process to another single-threaded process by acquire()/release()-ing on a named semaphore, for example.
In case the environment supports system interrupts it adds non-linear behaviour.
Semaphore can be used in order to sleep in main thread until interrupt triggers.