How to share a global object between threads? - c++

I have created a class, which has many public functions, some which write data and some that only read data.
It's required that I do this within 3 threads, I have no other option.
I know if I accessed a shared resource just to read, then I don't have to protect, but I don't know if it is any different when I am using a function to read a private variable of the shared resource.
E.g. I am trying to do...
globalObject.readColour();
which is a function that reads the colour of the global object.
Does it mean that I have to secure the thread at this point, or is it okay to just read the value without any risks?
I'm working on mbed, which supports c and c++98.

This question is similar to this one
If all your threads will only read the variable then you don't need mutex (or similar), but if any thread performs a writing operation you should use mutex.

Related

Is A Member Function Thread Safe?

I have in a Server object multiple thread who are doing the same task. Those threads are init with a Server::* routine.
In this routine there is a infinite loop with some treatments.
I was wondering if it was thread safe to use the same method for multiple threads ? No wonder for the fields of the class, If I want to read or write it I will use a mutex. But what about the routine itself ?
Since a function is an address, those thread will be running in the same memory zone ?
Do I need to create a method with same code for every thread ?
Ps: I use std::mutex(&Server::Task, this)
There is no problem with two threads running the same function at the same time (whether it's a member function or not).
In terms of instructions, it's similar to if you had two threads reading the same field at the same time - that's fine, they both get the same value. It's when you have one writing and one reading, or two writing, that you can start to have race conditions.
In C++ every thread is allocated its own call stack. This means that all local variables which exist only in the scope of a given thread's call stack belong to that thread alone. However, in the case of shared data or resources, such as a global data structure or a database, it is possible for different threads to access these at the same time. One solution to this synchronization problem is to use std::mutex, which you are already doing.
While the function itself might be the same address in memory in terms of its place in the table you aren't writing to it from multiple locations, the function itself is immutable and local variables scoped inside that function will be stacked per thread.
If your writes are protected and the fetches don't pull stale data you're as safe as you could possibly need on most architectures and implementations out there.
Behind the scenes, int Server::Task(std::string arg) is very similar to int Server__Task(Server* this, std::string arg). Just like multiple threads can execute the same function, multiple threads can also execute the same member function - even with the same arguments.
A mutex ensures that no conflicting changes are made, and that each thread sees every prior change. But since code does not chance, you don't need a mutex for it, just like you don't need a mutex for string literals.

Shared and local variables C++

I need to implement solution for readers writer problem in file system i'm developing. I was searching on the internet and found out this Wikipedia solution. Since I'm told no starving may exist I chose third solution. Now, I'm new in multithreaded programming and I have one question. How do I sepparate shared and local variables? I wanted to instantiate one ReadersWriters class in every file object that would manage accessing to that file, so every thread need to have it's own prev and current local variables and all of them need to share nreaders variable. I want to place them in ReadersWriters class.
As far as I know there are only two ways for the parent thread to share data with a child thread.
Global Variables
Passing it via a pointer during creation of the child thread.
Obviously new pointers may be tacked onto any existing objects.
Local variables with remain thread local unless you do something to prevent them from being so. Remember that each thread will have its own stack.

the variable with the same name in multi threads environment

I have a Class File. I created two threads A and B. In A and B, each thread, I create an auto varible File myfile. And then A and B will operate it. Is that secure? Will it lead to the inconsistent of data?
From the pure memory ressource perspective, it will depend on the scope of your File variables :
If they are local function variables, you are good to go. Each thread of execution owns it own stack, totally separate from other threads, where it create local variables.
If they are static, you are referring to the same global address.
From the file access perspective, it will depends if it is the same file, and if you are writing to it or not.
No, that shouldn't be a problem, simply because each instance of your thread has it's own instance of the variable.
Examine the addresses of the variables to be sure, if they differ (which they will if I understand you correctly), you're fine.
Inconsistencies between threads will only occur, if two threads concurrently access the same variable. Not just 'the same name', but really the same variable.
Now, if the variable was global and both threads were to access it, you'd need some sort of mutual exclusion to prevent data corruption, but auto-variables are safe.
The variables will be distint from each other as each thread will have its own stack, and each instance of the variable will live on that stack.
However, it sounds like you're accessing an underlying filesystem file. If it's the same file and one or both of the threads are writing to the file then this may cause data consistency issues. You'll need to consult the documentation for your operating system to see what it says. If both threads are just reading from the same file then you'll be fine.

When would one use Un-named shared memory?

When would you choose to use un-named shared memory in windows?
it seems to me that message passing between threads is not very useful. One can instead pass a pointer to a struct/variable to the worker threads, and use that as shared memory instead, rather than calling the CreateFileMapping system call.
One reason to use unnamed shared memory is to restrict access to the file mapping to only those processes who are given a handle to it by the creating process. This avoid two problems:
any process that knows the name and has sufficient access to create a mapped file can squat on your named object, preventing or interfering with its legitimate use - this allows a denial of service attack.
accidental rather than malicious name clashes.
When you don't use a name, you can be sure that only processes that you want to have access, get it. From the MSDN docs for CreateFileMapping:
A single file mapping object can be
shared by multiple processes through
inheriting the handle at process
creation, duplicating the handle, or
opening the file mapping object by
name.
Section objects (aka "file mapping objects") are not just used to share memory between processes. The most obvious use of section objects is to map in a file to do I/O, and giving the objects names wouldn't be very useful in most cases. For unnamed pagefile-backed sections ("shared memory") you can still make child processes inherit the handle so they can use the sections.
You can pass handles to unnamed objects across process boundaries. That is to say, you can actually create an unnamed memory map in your application, and access it from another without using a name!
Look at the DuplicateHandle call, which can be used to pass handles to unnamed objects across process boundaries.

pthread_key_t and pthread_once_t?

Starting with pthreads, I cannot understand what is the business with pthread_key_t and pthread_once_t?
Would someone explain in simple terms with examples, if possible?
thanks
pthread_key_t is for creating thread thread-local storage: each thread gets its own copy of a data variable, instead of all threads sharing a global (or function-static, class-static) variable. The TLS is indexed by a key. See pthread_getspecific et al for more details.
pthread_once_t is a control for executing a function only once with pthread_once. Suppose you have to call an initialization routine, but you must only call that routine once. Furthermore, the point at which you must call it is after you've already started up multiple threads. One way to do this would be to use pthread_once(), which guarantees that your routine will only be called once, no matter how many threads try to call it at once, so long as you use the same control variable in each call. It's often easier to use pthread_once() than it is to use other alternatives.
No, it can't be explained in layman terms. Laymen cannot successfully program with pthreads in C++. It takes a specialist known as a "computer programmer" :-)
pthread_once_t is a little bit of storage which pthread_once must access in order to ensure that it does what it says on the tin. Each once control will allow an init routine to be called once, and once only, no matter how many times it is called from how many threads, possibly concurrently. Normally you use a different once control for each object you're planning to initialise on demand in a thread-safe way. You can think of it in effect as an integer which is accessed atomically as a flag whether a thread has been selected to do the init. But since pthread_once is blocking, I guess there's allowed to be a bit more to it than that if the implementation can cram in a synchronisation primitive too (the only time I ever implemented pthread_once, I couldn't, so the once control took any of 3 states (start, initialising, finished). But then I couldn't change the kernel. Unusual situation).
pthread_key_t is like an index for accessing thread-local storage. You can think of each thread as having a map from keys to values. When you add a new entry to TLS, pthread_key_create chooses a key for it and writes that key into the location you specify. You then use that key from any thread, whenever you want to set or retrieve the value of that TLS item for the current thread. The reason TLS gives you a key instead of letting you choose one, is so that unrelated libraries can use TLS, without having to co-operate to avoid both using the same value and trashing each others' TLS data. The pthread library might for example keep a global counter, and assign key 0 for the first time pthread_key_create is called, 1 for the second, and so on.
Wow, the other answers here are way too verbose.
pthread_once_t stores state for pthread_once(). Calling pthread_once(&s, fn) calls fn and sets the value pointed to by s to record the fact it has been executed. All subsequent calls to pthread_once() are noops. The name should become obvious now.
pthread_once_t should be initialized to PTHREAD_ONCE_INIT.