I'm currently using QT (4) to parallelize a non-threadsafe library that's written in C by non-programmers, and thus has a lot of global variables. The threads don't need to interact or share data, they each just call a bunch of methods of the library and then at the end the library gives an output that is used further.
The problem is, though, that global variables are per default shared between threads, causing the library to crash in different places. There are two ways to fix this:
Refactor the entire library to not use global variables (ouch), or find a way to make global variables non-shared, or find a third magic way.
Is the latter an option with QT or standard (C++01) C++?
Using thread local storage is a way to make global variables non-shared. Starting point for that, with links to details for different implementations:
http://en.wikipedia.org/wiki/Thread-local_storage
You can't "unshare" global variables. The only available option for parallelization (bar refactoring) is to have multiple processes instead of multiple threads. Preferably pooled.
Create a singleton that is responsible for synchronizing the access to the global variables. The global variables become members of the new singleton class and can be accessed by methods that have the same names as your current global variables so you don't need to change code all over the place.
Related
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.
I know global variables are bad, however I have a checksettings function which is run every tick. http://pastebin.com/54yp4vuW The paste bin contains some of the check setting function. Before I added the GetPrivateProfileIntA everything worked fine. Now when I run it, it lags like hell. I can only assume this is because it is constantly loading the files. So my question is, are global variables constantly updated. (ie if I put this in global var will it stop the lag)
Thanks :)
Assuming I'm interpreting your question correctly, then no, global variables are not constantly updated unless you explicitly do so in code. So yes, putting those calls in global variables will get rid of the lag.
You haven't provided any details about the design but globals are visible across the entire application and get updated when they are written into.
Multiple processes/threads reading that global variable would then read the same updated value.
But synchronizing reads/writes requires the use of synchronization mechanisms such as mutexes, condition variables etc etc.
In your case you need to decide when to call GetPrivateProfileIntA() for all those settings.
Are all those settings constantly updated or only a fraction of those? Identify the ones which need to be monitored periodically and only load those.
And if a setting is stateful meaning all objects of the class refer to a single copy of the setting then I would use static class variables instead of plain global variables.
Alternately you could make a JIT call to GetPrivateProfileIntA() where needed and not bother about storing the setting in a global variable.
The question may be wrong in wording but the idea is simple. The order of initialisation of global objects in different translation units is not guarantied. If an application consists of two translation units - can compiler potentially generate initialisation code that will start two threads to create global objects in those translation units? This question is similar to this or this but I think the answers don't match the questions.
I will rephrase the question - if a program has several global objects - will their constructors always be called from the same thread (considering that user code doesn't start any threads before main)?
To make this question more practical - consider a case when several global objects are scattered over several translation units and each of them increments single global counter in constructor. If there is no guarantee that they are executed in single thread then access to the counter must be synchronised. For me it's definitely overkill.
UPDATE:
It looks like concurrent initialisation of globals is possible - see n2660 paper (second case)
UPDATE:
I've implemented singleton using singleton_registry. The idea is that declaration using SomeSingleton = singleton<SomeClass>; registers SomeClass for further initialisation in singleton_registry and real singleton initialisation (with all inter-dependencies) happens at the beginning of main function (before I've started any other threads) by singleton_registry (which is created on stack). In this case I don't need to use DLCP. It also allows me to prepare application configuration and disseminate it over all singletons uniformly. Another important use case is usage of singletons with TDD. Normally it's a pain to use singletons in unit tests, but with singleton_registry I can recreate application global objects for each test case.
In fact this is just a development of an idea that all singletons must be initialised at the beginning of function main. Normally it means that singleton user has to write custom initialisation function which handles all dependencies and prepare proper initialisation parameters (this is what I want to avoid).
Implementation looks good except the fact that I may have potential race conditions during singletons registration.
Several projects ago, using vxWorks and C++, a team mate used a non-thread safe pattern from the book (are any of those patterns thread safe?):
10% of system starts failed.
Lesson 1: if you don't explicitly control the when of a CTOR of a global object, it can change from build to build. (and we found no way to control it.)
Lesson 2: Controlling the when of CTOR is probably the easiest solution to lesson 1 (should it become a problem).
In my experience, if you gotta have Global objects (and it seems many would discourage it), consider limiting these globals to pointers initialized to 0:
GlobalObject* globalobject = nullptr;
And only the thread assigned to initialize it will do so. The other threads/tasks can spin wait for access.
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.
I am pretty sure these classes are not thread safe.
But, is it safe to use different objects from these classes in different threads?
Do they have any global dependencies with each other like static data or anything to watch out for?
As long as the calls you are making are to static functions that do not access shared memory (shared between threads).
Basically the only time you will hit a problem is if the function you call accesses shared data. If your function simply does some work on data you provide it is thread safe.