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. QtConcurrent single-threaded sequence processing
Forum Updated to NodeBB v4.3 + New Features

QtConcurrent single-threaded sequence processing

Scheduled Pinned Locked Moved Unsolved General and Desktop
3 Posts 3 Posters 1.2k Views 1 Watching
  • 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.
  • S Offline
    S Offline
    sgwr
    wrote on last edited by
    #1

    Hi

    I'm working on a QWidget application. I have a relatively long running task that I want to run in a background thread to avoid blocking the GUI thread. The task consist of sending a sequence of commands to a camera. This can be modeled as calling a function with a sequence of commands.

    I have looked through the documentation and came across QtConcurrent which filter, filter-reduce, map, map-reduce etc. Together with a QFutureWatcher this provides a lot of functionality out-of-the-box which I'd like to use (showing progress, cancellation, notification of the GUI thread etc.). I can pass my sequence of commands together with a function to send a command to the camera to some QtConcurrent function.

    My issue is that the order of commands is important. Therefore, I do not want multiple threads processing the command sequence in an arbitrary order but only a single thread processing the command sequence in a defined order.

    Can this somehow be achieved with the built-in higher level API's or do I have to resort using QtConcurrent::run() and implementing stuff like progress reporting etc. myself?

    1 Reply Last reply
    0
    • Gojir4G Offline
      Gojir4G Offline
      Gojir4
      wrote on last edited by
      #2

      Hello,

      I think this will be hard to achieve using QtConcurrent. Because you can only gives a pointer to a function for be run in a different thread, so you cannot connect some signals to indicate progress.

      But you could do it by calling QtConcurrent::run() for each of the command sent to the camera, so when a command is finished, you can send the next one, and then provide the progress quite easily.

      Another ways are to use QThread with the worker object approach, or QThreadPool and QRunnable. Both will require some extra work, but you will also have more possibilities.

      You can inherit from both QRunnable and QObject to provide signal monitoring signals, here is a small example:

      class HelloWorldTask : public QObject, public QRunnable
      {
          Q_OBJECT
          
          volatile bool m_abort;
          QReadWriteLock m_lock;
      public:
          void run()
          {
              emit started();
              qDebug() << "Hello world from thread" << QThread::currentThread();
              emit progressMaxChanged(10);
              emit progressValueChanged(0);        
              for(int i = 0; i < 10; i++){                  
                  if(isAborted())
                      break;
                  QThread::msleep(500);
                  emit progressValueChanged(i+1);        
              }
              emit finished();
          }
      public slots:
          void abort()    
          {        
            QWriteLocker locker(&m_lock)
            m_abort = true;
            lock.unlock();
          }
      protected:
          bool isAborted(){
              QReadLocker locker(&m_lock);
              return m_abort;
          }
      signals:
          void started();
          void progressValueChanged(int progress);
          void progressMaxChanged(int max);
          void finished();
      };
      
      HelloWorldTask *hello = new HelloWorldTask();
      connect(hello, &HelloWorldTask::started, this, &MyClass::onStarted);
      connect(hello, &HelloWorldTask::progressValueChanged, this, &MyClass::onProgressValueChanged);
      connect(hello, &HelloWorldTask::progressMaxChanged, this, &MyClass::onProgressMaxChanged);
      connect(hello, &HelloWorldTask::finished, this, &MyClass::onFinished);
      connect(this, &MyClass::abort, hello, &HelloWorldTask::abort);
      // QThreadPool takes ownership and deletes 'hello' automatically
      QThreadPool::globalInstance()->start(hello);
      

      Based on this you can reproduce almost the same behavior than QtConcurrent and QFuture and QFutureWatcher.

      1 Reply Last reply
      0
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #3

        Hi,

        Doing sequential work like that with Qt Concurrent is a bit of an oxymoron. From what you describe, it seems like a state machine would be more fitting to model what you want to do with your camera.

        See the The State Machine Framework chapter in Qt's documentation.

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        2

        • Login

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