Results 1 to 14 of 14

Thread: Globally accessible objects in threads

  1. #1
    Join Date
    Jan 2009
    Location
    Germany
    Posts
    387
    Thanks
    101
    Thanked 15 Times in 15 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Globally accessible objects in threads

    Hello everyone!

    I would like to find a nice solution to the following requirement. I need a globally accessible object, say an application wide Config. I use it in many places and preferably I would like to be able to access config variables anywhere in my code with config.variable. If it really really has to be, then I would accept the config->variable syntax implying that in this case Config is a pointer, which would bug me to no end because so far I made do without any pointers at all. Pointers are evil.

    Anyhow, the real complication is that my application has two threads. The gui thread and a worker thread. In the gui thread the config can be changed and then the worker thread has to be updated with the changes in a thread safe way. And there are many objects living in the worker thread, all of which need to have access to the Config object.

    So I'm asking you, how would you go about it?

  2. #2
    Join Date
    Sep 2009
    Location
    Wroclaw, Poland
    Posts
    1,394
    Thanked 342 Times in 324 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: Globally accessible objects in threads

    In the gui thread the config can be changed and then the worker thread has to be updated with the changes in a thread safe way
    Use signals & slots for this, they are thread safe. Let the config object emit a signal when it's changed.
    And there are many objects living in the worker thread, all of which need to have access to the Config object.
    If all you need is to notify the objects when config is changed, then your objects don't need to touch the config object. You can just send a signal with new configuration values to them.
    Maybe this way you can save the config object from being exposed to other threads. Create and modify it only in main thread, and use signals & slots to notify other threads about new config options.

  3. #3
    Join Date
    Jan 2009
    Location
    Germany
    Posts
    387
    Thanks
    101
    Thanked 15 Times in 15 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Globally accessible objects in threads

    Quote Originally Posted by stampede View Post
    Use signals & slots for this, they are thread safe.
    Yes, preferably. But as I said, there are many objects in the worker thread and I would like to avoid connecting each of them individually.
    It would be acceptable if all objects in the worker thread inherit from a "Configurable" and thus have their own instance of the config object.
    But I don't know if there is a way to make the connections implicitly in the super class so that I don't have to bother making them explicitly
    for every object I instantiate.

  4. #4
    Join Date
    Mar 2011
    Location
    Hyderabad, India
    Posts
    1,882
    Thanks
    3
    Thanked 452 Times in 435 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows
    Wiki edits
    15

    Default Re: Globally accessible objects in threads

    You need to make all the members of you config struct / class as atomic in nature.

    One of the simplest scenario is to have only integers (QAtomicInt) in config class, if you have complex data structures in config then you have no option, other than implementing you own thread-safe class using QMutex

    Anyhow, the real complication is that my application has two threads. The gui thread and a worker thread. In the gui thread the config can be changed and then the worker thread has to be updated with the changes in a thread safe way. And there are many objects living in the worker thread, all of which need to have access to the Config object.
    One possible solution to this scenario (if it fits you app), if your worker thread based on cycle / loop, where it can load the complete config structure into a thread local copy and then use it for rest of the loop / cycle, then load new copy of config next cycle (in thread-safe manner).

  5. #5
    Join Date
    Apr 2010
    Posts
    769
    Thanks
    1
    Thanked 94 Times in 86 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: Globally accessible objects in threads

    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.

  6. #6
    Join Date
    Sep 2009
    Location
    Wroclaw, Poland
    Posts
    1,394
    Thanked 342 Times in 324 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: Globally accessible objects in threads

    It would be acceptable if all objects in the worker thread inherit from a "Configurable" and thus have their own instance of the config object.
    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 settings (well, as long as those configs are not referencing the same shared data)

  7. #7
    Join Date
    Apr 2010
    Posts
    769
    Thanks
    1
    Thanked 94 Times in 86 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: Globally accessible objects in threads

    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.

  8. #8
    Join Date
    Jan 2009
    Location
    Germany
    Posts
    387
    Thanks
    101
    Thanked 15 Times in 15 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Globally accessible objects in threads

    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.

    Quote Originally Posted by SixDegrees View Post
    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 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.

  9. #9
    Join Date
    Sep 2009
    Location
    Wroclaw, Poland
    Posts
    1,394
    Thanked 342 Times in 324 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: Globally accessible objects in threads

    One config for all worker thread objects, or should they all have their individual copy.
    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.
    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.

  10. #10
    Join Date
    Jan 2009
    Location
    Germany
    Posts
    387
    Thanks
    101
    Thanked 15 Times in 15 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Globally accessible objects in threads

    Quote Originally Posted by stampede View Post
    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.
    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?

  11. #11
    Join Date
    Sep 2009
    Location
    Wroclaw, Poland
    Posts
    1,394
    Thanked 342 Times in 324 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: Globally accessible objects in threads

    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.
    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.
    In that case, just pick one schema and implement it, if you are satisfied with the results the great, if not, change the implementation

  12. #12
    Join Date
    Apr 2010
    Posts
    769
    Thanks
    1
    Thanked 94 Times in 86 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: Globally accessible objects in threads

    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.
    You can freely swap the words "reference" and "pointer" in these sentences and not change them in any meaningful way.

  13. #13
    Join Date
    Jan 2009
    Location
    Germany
    Posts
    387
    Thanks
    101
    Thanked 15 Times in 15 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Globally accessible objects in threads

    Quote Originally Posted by SixDegrees View Post
    You can freely swap the words "reference" and "pointer" in these sentences and not change them in any meaningful way.
    Well not exactly, because you can always declare a pointer, have it point at a random memory location and try to access it, while with references you can't. But anyhow. It's best to avoid both.

  14. #14
    Join Date
    Sep 2009
    Location
    Wroclaw, Poland
    Posts
    1,394
    Thanked 342 Times in 324 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: Globally accessible objects in threads

    I agree with SixDegrees, invalid references could be even more painful to debug, consider this:
    Qt Code:
    1. #include <iostream>
    2.  
    3. class Test{
    4. public:
    5. int x;
    6. };
    7.  
    8. int main( int argc, char ** argv ){
    9. Test * test = new Test();
    10. Test& ref = *test;
    11. ref.x = 10;
    12. std::cout << "value is " << ref.x;
    13. delete test;
    14. std::cout << "\nwhat now ? " << ref.x;
    15. // test->x = 0; // this will cause crash on my machine, line above not
    16. return 0;
    17. }
    To copy to clipboard, switch view to plain text mode 
    on my machine it prints:
    value is 10
    what now ? 7409624
    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.

Similar Threads

  1. globally re-orient the co-ordinate system
    By tomg_66 in forum Qt Programming
    Replies: 2
    Last Post: 21st October 2010, 23:49
  2. Replies: 3
    Last Post: 9th January 2010, 15:47
  3. Setting layout margin and spacing globally
    By aarpon in forum Qt Programming
    Replies: 0
    Last Post: 7th April 2009, 12:23
  4. using class objects globally??????
    By pratik in forum Qt Programming
    Replies: 2
    Last Post: 9th July 2007, 13:51
  5. Set QSettings::IniFormat globally?
    By Slip Nine in forum Newbie
    Replies: 2
    Last Post: 10th June 2006, 21:43

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.