In addition to the above, have a look at the QSettings object, which allows you to persist configuration changes across program runs. It already provides locking mechanisms.
In addition to the above, have a look at the QSettings object, which allows you to persist configuration changes across program runs. It already provides locking mechanisms.
I think you mean "have their own reference to the global config object", because having one config instance for every object makes it not very convenient to change the settingsIt would be acceptable if all objects in the worker thread inherit from a "Configurable" and thus have their own instance of the config object.(well, as long as those configs are not referencing the same shared data)
So there's a main thread a a worker thread. Only the main thread can change config settings; the worker thread objects only read from it.
Thread safety is not an issue here. The main thread makes its changes, then tells the worker thread objects a change has occurred. Maybe you want some kind of lock so the main thread won't change any values while the worker objects update themselves, but that isn't clear. If you roll your own notification system, similar to Java's event registration, you don't even need that; the main thread simply waits until the call to update the workers returns before it does anything else. There's probably a similar mechanism available through Qt's signal/slot framework. But a vector of pointers to every worker object is all that's needed here.
Store references in it if you can't get over your irrational dislike of pointers. You'll still be using pointers, but the syntax will let you fool yourself into thinking you're not.
I would like to avoid implementing thread safety with a locking mechanism, because my worker thread is fast steady paced (runs every 10 ms). So if the gui thread locks the config object to write updates into it, it might disrupt the steady pace of the worker thread, which is important to keep. But there is no problem transporting the config from the gui to the worker thread using signals and slots. The question is how to do it right on the other side. One config for all worker thread objects, or should they all have their individual copy. I'm sitll not sure how to do it best, there are so many options.
I think references are safer because they are const and the object they point has to exist when they are assigned. There are more possibilities to do something wrong with pointers. Probably 90% of all runtime errors is a result of using pointers.
Think about it, if all objects have different copies of config independent of each other, then how are you gonna change the config, without changing each local copy ? In that case you'll need to call threadObject->updateConfig(new_config) on every worker object, so this is not better than a signal & slot connection.One config for all worker thread objects, or should they all have their individual copy.
Only reason to have separate configs in each object I can think of, is that configs shares some underlying global config data, this way you can separate the thread-safety code to config class itself.
Yes, this is true. So let's say there is only one config object in the worker thread. Creating a reference or a pointer from all thread objects to the config is no less tedious than calling update on each of them or connecting every one of them to a signal. What happens if all worker thread objects are derived from ThreadObject that has a the config object as a static member? When a new config comes in from the gui through a slot, I only have to update the static config once and that should do it, right?
If thread objects are using shared data, then updating it once (in thread-safe way) will be enough.What happens if all worker thread objects are derived from ThreadObject that has a the config object as a static member? When a new config comes in from the gui through a slot, I only have to update the static config once and that should do it, right?
In that case, just pick one schema and implement it, if you are satisfied with the results the great, if not, change the implementationCreating a reference or a pointer from all thread objects to the config is no less tedious than calling update on each of them or connecting every one of them to a signal.![]()
You can freely swap the words "reference" and "pointer" in these sentences and not change them in any meaningful way.I think references are safer because they are const and the object they point has to exist when they are assigned. There are more possibilities to do something wrong with pointers. Probably 90% of all runtime errors is a result of using pointers.
I agree with SixDegrees, invalid references could be even more painful to debug, consider this:
on my machine it prints:Qt Code:
#include <iostream> class Test{ public: int x; }; int main( int argc, char ** argv ){ Test * test = new Test(); Test& ref = *test; ref.x = 10; std::cout << "value is " << ref.x; delete test; std::cout << "\nwhat now ? " << ref.x; // test->x = 0; // this will cause crash on my machine, line above not return 0; }To copy to clipboard, switch view to plain text mode
program runs without complains, while the "pointer" version nicely crashes. This is very simple example, but try to debug such errors with more complicated code. Not very pleasant experience.value is 10
what now ? 7409624
Bookmarks