I am reading the Threads in OS concepts and i come across "thread local storage (TLS)". What I understood is that the TLS is similar to static or global data, but it is more unique to individual thread. Its bit confusing on what is unique here?
Why can't we pass the data through runner (i.e., thread's actual codes) functions as params to this function?
Static and global data are shared across all the threads. If you modified a global/static variable it is visible to all the threads. Unlike global/shared variable if you create a variable in TLS, every thread has its own copy of the variable, i.e. changes to the variable is local to the thread. Unlike global variable where an access is made through ds segment, the TLS variable are accessed using (gs/fs) segment. A good way to learn about it is to look at the disassembly generated by the compiler.
Let's supposed you are working in Ada. In your Ada program you define a task (thread) that includes a [static] variable that can only be accessed by the task. You now create multiple instances of your task. Then you need a copy of that [static] variable for each task.
That's where your implementation could use Thread Local Storage. In other words, it is a static area of memory that gets copied for each thread in a program.
As an alternative to TLS, a thread could allocate such storage at the top of the stack.
We need thread-local storage to create libraries that have thread-safe functions, because of the thread-local storage each call to a function has its copy of the same global data, so it's safe I like to point out that the implementation is the same for copy on write technique.
in normal function with global data, the content of that data can be updated by multiple threads and make it unreliable, but in thread-local storage, you can think of it as
"global became local when multiple access happen "
Related
I am creating a webserver using tokio. Whenever a client connection comes in, a green thread is created via tokio::spawn.
The main function of my web server is proxy. Target server information for proxy is stored as a global variable, and for proxy, all tasks must access the data. Since there are multiple target servers, they must be selected by round robin. So the global variable (struct) must have information of the recently selected server(by index).
Concurrency problems occur because shared information can be read/written by multiple tasks at the same time.
According to the docs, there seems to be a way to use Mutex and Arc or a way to use channel to solve this.
I'm curious which one you usually prefer, or if there is another way to solve the problem.
If it's shared data, you generally do want Arc, or you can leak a box to get a 'static reference (assuming that the data is going to exist until the program exits), or you can use a global variable (though global variables tends to impede testability and should generally be considered an anti-pattern).
As far as what goes in the Arc/Box/global, that depends on what your data's access pattern will be. If you will often read but rarely write, then Tokio's RwLock is probably what you want; if you're going to be updating the data every time you read it, then use Tokio's Mutex instead.
Channels make the most sense when you have separate parts of the program with separate responsibilities. It doesn't work as well to update multiple workers with the same changes to data, because then you get into message ordering problems that can result in each worker's state disagreeing about something. (You get many of the problems of a distributed system without any of the benefits.)
Channels can work if there is a single entity responsible for maintaining the data, but at that point there isn't much benefit over using some kind of mutual exclusion mechanism; it winds up being the same thing with extra steps.
In ESQL we have SHARED CONSTANTS, Why do we need them when they are constant and they don't change even if multiple threads access the same value.
DECLARE MYCONST SHARED CONSTANT CHAR 'My Constant';
OR in general I would like to know why do we need shared constants??
Using my immagination, you can declare a constant shared to not duplicate a BIG variable among Flows.
For Example, it could be useful in a multiple instances flow if you want to send a every-time-the-same message and you want to save time.
It could be already in memory with:
DECLARE MYVAR SHARED CONSTANT BLOB X'0000' ;
I think that this need is very much infrequent.
And even more infrequent to take advantage from this: if the blob is too big simply is counterproductive to put in a global variable.
According to this post, it takes more time to read a SHARED CONSTANT than a normal CONSTANT. There seems to be a locking mechanism for all shared variables, including constants.
But probably all non shared CONSTANTs are copied to the memory at the start of each flow instance. I would say, if you have a lot of constants and each flow only accesses a few of them, SHARED CONSTANTS are more performant.
If performance is an issue, I would test which option processes the data in less time. But there is no solution that is best for every single messageflow.
Actually I am using visual C++ to try to bind lua functions as callbacks for socket events(in another thread). I initialize the lua stuff in one thread and the socket is in another thread, so every time the socket sends/receives a message, it will call the lua function and the lua function determines what it should do according to the 'tag' within the message.
So my questions are:
Since I pass the same Lua state to lua functions, is that safe? Doesn't it need some kinda protection? The lua functions are called from another thead so I guess they might be called simultaneously.
If it is not safe, what's the solution for this case?
It is not safe to call back asynchronously into a Lua state.
There are many approaches to dealing with this. The most popular involve some kind of polling.
A recent generic synchronization library is DarkSideSync
A popular Lua binding to libev is lua-ev
This SO answer recommends Lua Lanes with LuaSocket.
It is not safe to call function within one Lua state simultaneously in multiple threads.
I was dealing with the same problem, since in my application all basics such as communication are handled by C++ and all the business logic is implemented in Lua. What I do is create a pool of Lua states that are all created and initialised on an incremental basis (once there's not enough states, create one and initialise with common functions / objects). It works like this:
Once a connection thread needs to call a Lua function, it checks out an instance of Lua state, initialises specific globals (I call it a thread / connection context) in a separate (proxy) global table that prevents polluting the original global, but is indexed by the original global
Call a Lua function
Check the Lua state back in to the pool, where it is restored to the "ready" state (dispose of the proxy global table)
I think this approach would be well suited for your case as well. The pool checks each state (on an interval basis) when it was last checked out. When the time difference is big enough, it destroys the state to preserve resources and adjust the number of active states to current server load. The state that is checked out is the most recently used among the available states.
There are some things you need to consider when implementing such a pool:
Each state needs to be populated with the same variables and global functions, which increases memory consumption.
Implementing an upper limit for state count in the pool
Ensuring all the globals in each state are in a consistent state, if they happen to change (here I would recommend prepopulating only static globals, while populating dynamic ones when checking out a state)
Dynamic loading of functions. In my case there are many thousands of functions / procedures that can be called in Lua. Having them constantly loaded in all states would be a huge waste. So instead I keep them byte code compiled on the C++ side and have them loaded when needed. It turns out not to impact performance that much in my case, but your mileage may vary. One thing to keep in mind is to load them only once. Say you invoke a script that needs to call another dynamically loaded function in a loop. Then you should load the function as a local once before the loop. Doing it otherwise would be a huge performance hit.
Of course this is just one idea, but one that turned out to be best suited for me.
It's not safe, as the others mentioned
Depends on your usecase
Simplest solution is using a global lock using the lua_lock and lua_unlock macros. That would use a single Lua state, locked by a single mutex. For a low number of callbacks it might suffice, but for higher traffic it probably won't due to the overhead incurred.
Once you need better performance, the Lua state pool as mentioned by W.B. is a nice way to handle this. Trickiest part here I find synchronizing the global data across the multiple states.
DarkSideSync, mentioned by Doug, is useful in cases where the main application loop resides on the Lua side. I specifically wrote it for that purpose. In your case this doesn't seem a fit. Having said that; depending on your needs, you might consider changing your application so the main loop does reside on the Lua side. If you only handle sockets, then you can use LuaSocket and no synchronization is required at all. But obviously that depends on what else the application does.
I've using the QT API in C++, but I imagine answers can come effectively from people without any prior experience with QT.
QT has a function in its XML-handling class, called setContent(), which is specified as non-reentrant. When called, setContent() reads an XML file into memory, and returns it as a data structure.
As I understand it, a non-reentrant function is one that is not safe to call simultaneously from multiple threads even if the function is called to operate on different files/objects.
So based on this, my understanding is that I would not be able to have more than one thread that opens XML files using this function unless somehow both of these threads are protected against accessing the setContent() function at the same time.
Is this correct? If so, seems like a really poor way to write an API as this doesn't seem like a function at all that intuitively would raise multi-threading problems. In addition, no mutex is provided at all by the API.
So in order to use this function in my multi-threaded program, where more than one thread will be opening different XML files, what's the best way to handle access to the setContent() function? Should I create an extern mutex in a header file on its own that is included by every file that will access XML?
Looks like it's all about static QDomImplementation::InvalidDataPolicy invalidDataPolicy. It's the only static data that QDom*** classes use.
setContent and a bunch of global functions use its value when parsing, and if another thread changes it in the middle, obviously something may happen.
I suppose if your program never calls setInvalidDataPolicy(), you're safe to parse XML from different threads.
So based on this, my understanding is that I would not be able to have
more than one thread that opens XML files using this function unless
somehow both of these threads are protected against accessing the
setContent() function at the same time.
I think you're correct.
So in order to use this function in my multi-threaded program, where
more than one thread will be opening different XML files, what's the
best way to handle access to the setContent() function? Should I
create an extern mutex in a header file on its own that is included by
every file that will access XML?
Again, I tend to agree with you regarding the mutex. (By the way, Qt provides the QMutex) But I'm not sure what you mean by an extern mutex in a header file, so I'll just make sure to instantiate exactly one mutex, and dispatch a pointer to this mutex to all the threads that require it.
I think this might be a fairly easy question.
I found a lot of examples using threads and shared variables but in no example a shared variable was created inside a thread. I want to make sure I don't do something that seems to work and will break some time in the future.
The reason I need this is I have a shared hash that maps keys to array refs. Those refs are created/filled by one thread and read/modified by another (proper synchronization is assumed). In order to store those array refs I have to make them shared too. Otherwise I get the error Invalid value for shared scalar.
Following is an example:
my %hash :shared;
my $t1 = threads->create(
sub { my #ar :shared = (1,2,3); $hash{foo} = \#ar });
$t1->join;
my $t2 = threads->create(
sub { print Dumper(\%hash) });
$t2->join;
This works as expected: The second thread sees the changes the first made. But does this really hold under all circumstances?
Some clarifications (regarding Ian's answer):
I have one thread A reading from a pipe and waiting for input. If there is any, thread A will write this input in a shared hash (it maps scalars to hashes... those are the hashes that need to be declared shared as well) and continues to listen on the pipe. Another thread B gets notified (via cond_wait/cond_signal) when there is something to do, works on the stuff in the shared hash and deletes the appropriate entries upon completion. Meanwhile A can add new stuff to the hash.
So regarding Ian's question
[...] Hence most people create all their shared variables before starting any sub-threads.
Therefore even if shared variables can be created in a thread, how useful would it be?
The shared hash is a dynamically growing and shrinking data structure that represents scheduled work that hasn't yet been worked on. Therefore it makes no sense to create the complete data structure at the start of the program.
Also the program has to be in (at least) two threads because reading from the pipe blocks of course. Furthermore I don't see any way to make this happen without sharing variables.
The reason for a shared variable is to share. Therefore it is likely that you will wish to have more than one thread access the variable.
If you create your shared variable in a sub-thread, how will you stop other threads accessing it before it has been created? Hence most people create all their shared variables before starting any sub-threads.
Therefore even if shared variables can be created in a thread, how useful would it be?
(PS, I don’t know if there is anything in perl that prevents shared variables being created in a thread.)
PS A good design will lead to very few (if any) shared variables
This task seems like a good fit for the core module Thread::Queue. You would create the queue before starting your threads, push items on with the reader, and pop them off with the processing thread. You can use the blocking dequeue method to have the processing thread wait for input, avoiding the need for signals.
I don't feel good answering my own question but I think the answers so far don't really answer it. If something better comes along, I'd be happy to accept that. Eric's answer helped though.
I now think there is no problem with sharing variables inside threads. The reasoning is: Threads::Queue's enqueue() method shares anthing it enqueues. It does so with shared_clone. Since enqueuing should be good from any thread, sharing should too.