Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QMutex & QWaitCondition usage
QtWS25 Last Chance

QMutex & QWaitCondition usage

Scheduled Pinned Locked Moved Solved General and Desktop
7 Posts 2 Posters 1.0k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    R Offline
    rtavakko
    wrote on last edited by
    #1

    Hey guys,

    I'm trying to understand and clarify how to use QMutex and QWaitCondition for synchronization across two threads. Let's say I have a producer and consumer object like in the wait conditions example.

    The producer creates an array of data and sends it to the consumer to read. And the consumer is expected to notify the producer when it is finished reading the data.

    The producer class would be something like this:

    class Producer : public QThread
    {
        Q_OBJECT
    private:
        QMutex readMutex;
        QWaitCondition readCondition;
        
        unsigned char* data = nullptr;
        
    public:
        Producer(QObject *parent = NULL) : QThread(parent)
        {
        }
    
        void run() override
        {
            data = new unsigned char[8];
            memset(data, 255, 8*sizeof(unsigned char));
            
            mutex.lock();
            emit dataReady(data, &readMutex, &readCondition);
            readCondition.wait(&mutex);
            delete data;
            data = nullptr;
            mutex.unlock();
        }
    
    signals:
        void dataReady(unsigned char* readData, QMutex* mutex, QWaitCondition* condition);
    };
    

    And the consumer class would be:

    class Consumer : public QThread
    {
    public:
        Consumer(QObject *parent = NULL) : QThread(parent)
        {
        }
    public slots:
        void processData(unsigned char* readData, QMutex* mutex, QWaitCondition* condition)
        {
            //Data processing stuff//
            
            QMutexLocker(mutex);
            condition -> notify_all();
        }
    };
    

    Would this be the correct use of the mechanism? Does the consumer need to do anything with the mutex at all or does it only need the wait condition so it can notify the producer?

    Cheers!

    1 Reply Last reply
    0
    • R Offline
      R Offline
      rtavakko
      wrote on last edited by rtavakko
      #7

      It seems what I'm seeing is the spurious / lost wake up side effect build into the wait condition mechanism especially given that this is a very basic example. I have yet to do more testing with this but so far it seems adding a simple method similar to this in the worker thread fixes the issue:

      bool readPredicate = false;
      unsigned long t_readTimeOut = 50;
      
      bool Producer::waitForFrameRead()
      {
          bool timedOut = false;
          while(!readPredicate)
          {
              timedOut = !frameProcessed.wait(&mutex, t_readTimeOut);
          }
          return timedOut;
      }
      

      The consumer would access the readPredicate boolean and set it to true when it is done processing data.

      I'm not sure if this is the best way to get around the issue, I would definitely appreciate it if anyone with experience on this can share their knowledge.

      Cheers!

      1 Reply Last reply
      0
      • Christian EhrlicherC Offline
        Christian EhrlicherC Offline
        Christian Ehrlicher
        Lifetime Qt Champion
        wrote on last edited by
        #2

        Please take a look at https://doc.qt.io/qt-5/qtcore-threads-waitconditions-example.html

        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
        Visit the Qt Academy at https://academy.qt.io/catalog

        R 1 Reply Last reply
        1
        • Christian EhrlicherC Christian Ehrlicher

          Please take a look at https://doc.qt.io/qt-5/qtcore-threads-waitconditions-example.html

          R Offline
          R Offline
          rtavakko
          wrote on last edited by
          #3

          @Christian-Ehrlicher Thanks. I've based the code I posted above on the example. What I'm not sure about is if the consumer only needs to notify the producer or if it also needs to lock and unlock the mutex.

          1 Reply Last reply
          0
          • Christian EhrlicherC Offline
            Christian EhrlicherC Offline
            Christian Ehrlicher
            Lifetime Qt Champion
            wrote on last edited by
            #4

            The exmaple is correct, so why do you want to use an extra mutex?

            Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
            Visit the Qt Academy at https://academy.qt.io/catalog

            1 Reply Last reply
            0
            • R Offline
              R Offline
              rtavakko
              wrote on last edited by
              #5

              I have multiple producers working with one consumer. After a few cycles, the consumer fails to wake up one of the producers. It sends the wake signal but it is never received. If I put in the QMutexLocker line it works ok:

              QMutexLocker(mutex);
              condition -> notify_all();
              

              I'm not sure why this happens but it seems to happen more often during keyboard events, switching between different windows etc.

              In the producer do I need to use QMutexLocker instead of locking and unlocking the mutex?

              1 Reply Last reply
              0
              • R Offline
                R Offline
                rtavakko
                wrote on last edited by
                #6
                This post is deleted!
                1 Reply Last reply
                0
                • R Offline
                  R Offline
                  rtavakko
                  wrote on last edited by rtavakko
                  #7

                  It seems what I'm seeing is the spurious / lost wake up side effect build into the wait condition mechanism especially given that this is a very basic example. I have yet to do more testing with this but so far it seems adding a simple method similar to this in the worker thread fixes the issue:

                  bool readPredicate = false;
                  unsigned long t_readTimeOut = 50;
                  
                  bool Producer::waitForFrameRead()
                  {
                      bool timedOut = false;
                      while(!readPredicate)
                      {
                          timedOut = !frameProcessed.wait(&mutex, t_readTimeOut);
                      }
                      return timedOut;
                  }
                  

                  The consumer would access the readPredicate boolean and set it to true when it is done processing data.

                  I'm not sure if this is the best way to get around the issue, I would definitely appreciate it if anyone with experience on this can share their knowledge.

                  Cheers!

                  1 Reply Last reply
                  0

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved