Waiting for QThreads to finish



  • I have a data model for a Qt GUI I am writing. There can be multiple async update to the model and the async task completion time may not mimic the order of starting time. I want to update GUI, only when all running async tasks have finished. (The async tasks are QThreads).

    How can I implement this in Qt?



  • @ajaxcrypto
    Excuse me, you say that while QThread working, do not click on Form (QPushbutton, QLienedit ...)?
    If not, why do you need QThread?



  • No, I want the application to be responsive, the async operation does not block the GUI, and there might be multiple async operations doing different tasks. But, once they have all finished, I want to update something in the GUI i.e. execute a function from GUI thread i.e.

    start_multiple_threads();
    QObject::connect(??, magic_all_other_threads_finished_signal, guiObject, []{ doSomething(); });
    

  • Qt Champions 2016

    Please post some code of how you set up the threads and how you signal the finish of the operation. What threading technology do you use?



  • @ajaxcrypto said in Waiting for QThreads to finish:

    No, I want the application to be responsive, the async operation does not block the GUI, and there might be multiple async operations doing different tasks. But, once they have all finished, I want to update something in the GUI i.e. execute a function from GUI thread i.e.

    You dont need a finished SIGNAL. You need to understand your gui that something happened.

    @ajaxcrypto

    signals:
        void loaded(int); 
    
    public slots:
        void run() {
            int i = 0;
            forever {
                emit loaded(i++);
                this->msleep(25);
            }
        }
    

    @ajaxcrypto said in Waiting for QThreads to finish:

    start_multiple_threads();
    QObject::connect(??, magic_all_other_threads_finished_signal, guiObject, []{ doSomething(); });

    MyThread *thrd = new MyThread();
    connect(thrd,  &MyThread::loaded,  this,  [=](int value) {// do something});
    thrd->start();
    


  • There is a very good tutorial for QThreads at https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/

    When you override run like you are, you are blocking the thread's event loop. You could do the same by having your worker object run in a 25ms timer. Connect the worker object to the thread as suggested in the article. Have the run entry point of the object start the timer and just emit your loaded signal as designed.

    This is truly the best way to run threads. You can then request termination and they will stop. For example:

    void Worker::start ()
    {
    m_timerId = startTimer (25);
    m_count = 0;
    }

    void Worker::timerEvent (QTimerEvent* event)
    {
    if (event->timerId () == m_timerId) {
    Q_EMIT loaded (m_count++);
    return;
    }
    QObject::timerEvent (event);
    }

    Worker* worker = new Worker; // QObject derived
    QThread* thread = new QThread;

    // Connect the signals for handling thread processing
    connect (thread, &QThread::started, worker, &start);
    connect (thread, &QThread::finished, worker, &finished);
    connect (this, &finished, worker, &deleteLater);
    connect (thread, &QThread::finished, thread, &QThread::deleteLater);

    // Move this object to the thread and start it
    worker->moveToThread (thread);
    thread->start ();

    blah blah blah

    thread->requestInteruption ();
    thread->wait ();

    This will clean up memory and not use the dreaded sleep but always work on the timer in the thread's own event queue.


  • Lifetime Qt Champion

    Hi,

    What kind of operations are you doing ?



  • Guys, I have solved the issue. I am using multiple concurrent running QThread, and using signals to update and know when all have finished.



  • @ajaxcrypto glad you solved your issue. Could it be possible to mark your post as such then? Thanks.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.