Results 1 to 5 of 5

Thread: Threads and mutable variables

  1. #1
    Join Date
    Dec 2010
    Location
    Ottawa, On, Canada
    Posts
    11
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Threads and mutable variables

    Good morning,

    I am doing some refactoring and I came across the following issue. I am running a multi-thread program, where a pair of threads (call the writingThread and readingThread) are accessing a shared object. One thread is processing an image and sets a data member in the shared object when the desired condition occurs while the second thread (readingThread) waits for the given condition (data member set to continue its process).

    The shared object has the following declaration:

    Qt Code:
    1. class TargetTracking : public QObject
    2. {
    3. ...
    4. public:
    5. bool isTargetAligned() { return m_targetIsAligned; }
    6. void overrideTargetAlignment( const bool action) { m_overrideTargetAlignment = action; }
    7. void waitForAlign();
    8.  
    9. private:
    10. bool m_targetIsAligned;
    11. bool m_overrideTargetAlignment;
    12. }
    To copy to clipboard, switch view to plain text mode 
    Both threads have a pointer to TargetTracking object as data member.

    Prior to the refactoring, the code was working correctly. However, the data member m_targetIsAligned was declared as a member of writingThread, and readingThread was calling and waiting for writingThread::waitForAlign() to return. The refactoring process included moving code form writingThread to TargetTracking class as shown above.

    After some tests, I was only able to make the code work if the mutable keyword was added to the declaration of the two booleans

    Qt Code:
    1. private:
    2. mutable bool m_targetIsAligned;
    3. mutable bool m_overrideTargetAlignment;
    4. }
    To copy to clipboard, switch view to plain text mode 
    I have done some reading about the use of mutable; ie 'casting away const', however, I am lost as for why it is required in this case. Before using mutable, I tried wrapping the access to the booleans using mutex but that did not work either.

    So my question is why the mutable attribute required here?

    Thanks in advance
    Daniel

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Threads and mutable variables

    The code above doesn't enforce the use of mutable. It is the code that you didn't post that requires it. Somewhere in your code you have a method declared as const or accepting the TargetTracking instance as a const object and some code is trying to change this const (through inheritance from the class) member which is forbidden. Therefore rather than using "mutable", you should pay attention to your const methods and const objects. Use mutable only as a means of last resort or when you know what you are doing (e.g. when implementing a cache that needs to be built from within a const method). And of course this is plain C++, nothing Qt specific.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #3
    Join Date
    Dec 2010
    Location
    Ottawa, On, Canada
    Posts
    11
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Threads and mutable variables

    Thanks for the reply.

    The shared object (TargetTracking) is instantiated in the gui thread and passed as a constructor argument for the reading and writing threads

    Qt Code:
    1. m_targetTracking = new TargetTracking( ...);
    2. m_targetTrackingThread = new TargetTrackingThread( m_targetTracking); // writing thread
    3. m_targetTrackingThread->start();
    To copy to clipboard, switch view to plain text mode 

    The TargetTrakingThread is declared as
    Qt Code:
    1. class TargetTrakingThread : public QThread {
    2. Q_OBJECT
    3.  
    4. public:
    5. TargetTrakingThread( TargetTracking* targetTracking);
    6. ~TargetTrakingThread();
    7.  
    8. void autoTargetAlign();
    9. void stopTargetAlign() { m_stop = true; }
    10.  
    11. protected:
    12. void run();
    13.  
    14. private:
    15. TargetTracking* targetTracking;
    16. bool m_stop;
    17. };
    To copy to clipboard, switch view to plain text mode 
    The waitForAlign method is essentially polling the data member and is defined as
    Qt Code:
    1. void TargetTracking::waitForAlign()
    2. {
    3. while (!m_targetIsAligned && m_autoTargetAlign) {
    4. usleep( 100000);
    5. }
    6. }
    To copy to clipboard, switch view to plain text mode 
    This method is called by the readingThread

    The data member m_targetIsAligned is set in a different method TargetTracking::alignTarget as shown

    Qt Code:
    1. void TargetTracking::alignTarget()
    2. {
    3. ...
    4. locateTarget();
    5.  
    6. // check if the target is centred
    7. if (!m_overrideTargetlAlignment) {
    8. m_targetIsAligned = checkIfTargetCentred();
    9. } else {
    10. m_targetIsAligned = true;
    11. }
    12. ...
    13. }
    To copy to clipboard, switch view to plain text mode 
    This method is called by the writing thread

    I reviewed the code, and the only instance where const appears is in the different get methods for the TargetTracking data members. There are two methods setting the control booleans and are defined as

    Qt Code:
    1. class TargetTracking : public QObject
    2. {
    3. ...
    4. void setAutoTargetAlign( const bool align) { m_autoTargetAlign = align; }
    5. void overrideTargetAlignment( const bool action) { m_overrideTargetAlignment = action; }
    6. ...
    7. }
    To copy to clipboard, switch view to plain text mode 

    Could these instance of const be the root of my problem?
    Also, there is no inheritance for the classes mentioned here. Note that TargetTracking has some static methods declared

    So the addition of the mutable attribute still puzzle me.

    Daniel

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Threads and mutable variables

    Why aren't you just using a wait condition? Using such a spinlock as yours waitForAlign is very heavy for your cpu and it's prone to race conditions.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  5. #5
    Join Date
    Dec 2010
    Location
    Ottawa, On, Canada
    Posts
    11
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Threads and mutable variables

    This was to be my next step in refactoring the code.

    I did replace polling by a QWaitCondition in the waitForAlign() method, removed the mutable attribute and now the code is working as expected.

    Thanks again,
    Daniel

Similar Threads

  1. How to actually connect variables to the GUI ?
    By Computer Hater in forum Newbie
    Replies: 6
    Last Post: 14th November 2010, 23:49
  2. Qt Threads vs Native Threads performance
    By StackOverflow in forum Qt Programming
    Replies: 1
    Last Post: 14th November 2010, 12:14
  3. Casting variables
    By axisdj in forum Newbie
    Replies: 1
    Last Post: 6th September 2010, 17:00
  4. variables and formulas
    By michael1953 in forum Newbie
    Replies: 3
    Last Post: 13th February 2007, 06:53
  5. Qt and global variables
    By Morea in forum Qt Programming
    Replies: 11
    Last Post: 1st February 2007, 23:42

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.