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. Need help with multithreading
Qt 6.11 is out! See what's new in the release blog

Need help with multithreading

Scheduled Pinned Locked Moved General and Desktop
qfuturewatcherqfuture
5 Posts 2 Posters 2.1k 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.
  • Q Offline
    Q Offline
    qounce
    wrote on last edited by koahnig
    #1

    Hi. I have a function which I want to call with few instances in several threads. I suppose to use something like that:

    void MainWindow::btn_clicked () {
        for (int i = 0; i < 10; ++i) {
            // different parts computing in different threads
            Function(a,b); // thread 1
            Function(b,c); // thread 2
    
            // after tasks in all threads are done
            UpdateMap(); // update QGrapchicScene
            sleep(delay); // pause
        }
    }
    

    But during cycle is proceeding GUI should not be frozen.
    So, what is the best practice to do that? QThreads or QConcurrent or something else?

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

      Hi,

      QtConcurrent sounds like a good choice. However, the UpdateMap function should be connected to a QFutureWatcher to only run once all operations are done.

      Why the call to sleep ?

      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
      0
      • Q Offline
        Q Offline
        qounce
        wrote on last edited by koahnig
        #3

        I need pause just to see updated map.
        Well, I'm trying to find out how to use QtConcurrent right now, but there is no significant success. I try:

        future1 = new QFuture<void>;
        watcher1 = new QFutureWatcher<void>;
        future2 = new QFuture<void>;
        watcher2 = new QFutureWatcher<void>;
        connect(watcher1, SIGNAL(finished()),
                       this, SLOT(S()));
        connect(watcher2, SIGNAL(finished()),
                       this, SLOT(S()));
        
        size_t s = fieldSizeI / 2;
        for (size_t i = 0; i < 10; ++i) {
            *future1 = QtConcurrent::run(field, &Field::PerformIteration, 0, s);
            *future2 = QtConcurrent::run( field, &Field::PerformIteration, s, 2*s);
        
            watcher1->setFuture(*future1);
            watcher2->setFuture(*future2);
        }
        
        void MainWindow::S() {
            ++workCounter;
            if (workCounter == 2) {
                field->AdoptNewState();
                UpdateMap();
                workCounter = 0;
            }
        }
        

        It seems I'am doing it absolutely wrong. And I can't find an appropriate example.

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by koahnig
          #4
          QFutureWatcher *watcher1 = new QFutureWatcher<void>;
          QFutureWatcher *watcher2 = new QFutureWatcher<void>;
          connect(watcher1, SIGNAL(finished()),
                         this, SLOT(S()));
          connect(watcher2, SIGNAL(finished()),
                         this, SLOT(S()));
           
          size_t s = fieldSizeI / 2;
          
              QFuture<void> future1 = QtConcurrent::run(field, &Field::PerformIteration, 0, s);
          QFuture<void> future2 = QtConcurrent::run( field, &Field::PerformIteration, s, 2*s);
           
              watcher1->setFuture(future1);
              watcher2->setFuture(future2);
          }
          

          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
          0
          • Q Offline
            Q Offline
            qounce
            wrote on last edited by koahnig
            #5

            Thanks. I used your code to construct the thing below. It looks not so hot but work just how I need.

            // call this function to start
            void MainWindow::on_btn_iter_clicked()
            {
                maxIter = 5;
                s = fieldSizeI / threadsAmount;
                NewIteration();
            }
            
            void MainWindow::NewIteration() {
                std::vector<QFutureWatcher<void> *> watchers (threadsAmount);
                for (size_t i = 0; i < threadsAmount; ++i) {
                    watchers[i] = new QFutureWatcher<void>;
                    connect (watchers[i], SIGNAL (finished()), this, SLOT (S()));
                }
                typedef std::vector<QFuture<void> > futures (threadsAmount);
                for (size_t i = 0; i < threadsAmount; ++i) {
                    futures[i] = QtConcurrent::run(field, &CA_Field::PerformIteration,
                                                   i*s, (i+1)*s );
                    watchers[i]->setFuture(futures[i]);
                }
            }
            
            void MainWindow::S() {
                ++workCounter;
                if (workCounter == threadsAmount) {
                    field->AdoptNewState();
                    workCounter = 0;
                    (--maxIter != 0) ? NewIteration() : UpdateHexMap();
                }
            }
            
            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