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. Why QThread still working, when work is done?
Forum Updated to NodeBB v4.3 + New Features

Why QThread still working, when work is done?

Scheduled Pinned Locked Moved Unsolved General and Desktop
15 Posts 5 Posters 1.0k 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 qwe3

    Hi,

    I have simple app with 2 threads: main and one for heavy calculations.

    When the calculations are in progress I close app using X button. So my code goes to MainWindow destructor and I have here:

        thread->quit();
    
        qInfo()<<"BEFORE WAIT";
        thread->wait();
        qInfo()<<"AFTER WAIT";
    

    I quit second thread, so my second thread exit event loop. But of course it still calculates. On main thread I wait on line thread->wait(). But when the second thread ends calculates ( I see on debuq "END" ), I think the second thread did the work, there is no event loop in second thread, so work for second thread is over. But I still wait on thread->wait(). And I will wait forever... Why this is happening?

    My whole code:
    MainWindow ( main thread ) :

    constructor:
    
        thread = new QThread(this);
        worker = new Worker;
    
        connect(this, &MainWindow::start, worker, &Worker::calculate);
    
        worker->moveToThread(thread);
    
        thread->start();
    
        emit start();
    
    destructor:
    
        thread->quit();
    
        qInfo()<<"BEFORE WAIT";
        thread->wait();
        qInfo()<<"AFTER WAIT";
    

    Second thread ( heavy calculations ) :

    void Worker::calculate()
    {
        double z = 21;
        for(int i=0;i<100000000;i++)
        {
            if(i%5000000 == 0) // to see that thread works
            {
                QCoreApplication::processEvents();
                qDebug()<<i;
            }
    
            z+=qSin(i*0.32)*qCos(i/2*0.31);  // some heavy calculations 
            z+=10.00/(i+1);
        }
        qInfo()<<"END";
    }
    

    And my debuq:

    0
    5000000
    10000000
    15000000
    20000000
    25000000
    BEFORE WAIT
    30000000
    35000000
    40000000
    45000000
    50000000
    55000000
    60000000
    65000000
    70000000
    75000000
    80000000
    85000000
    90000000
    95000000
    END
    13:58:51: The program has unexpectedly finished.  // because I stop program using Qt Creator
    
    JKSHJ Offline
    JKSHJ Offline
    JKSH
    Moderators
    wrote on last edited by
    #2

    @qwe3 said in Why QThread still working, when work is done?:

    I quit second thread, so my second thread exit event loop.

    Calling quit() tells the event loop to stop running. However, it has no effect on your for-loop.

    If you want to interrupt the calculation, then you must call break; from inside your for-loop.

    Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

    1 Reply Last reply
    3
    • Q Offline
      Q Offline
      qwe3
      wrote on last edited by qwe3
      #3

      @JKSH Thank you for answer. I know that I have to use isInterruptionRequested() and requestInterruption(). But now I ask about something different.

      I would like ( now ) to have an application, which calculate what I want ( calculate() method in second thread ) even if I close the application. But when it finish calculates, application should close in correct way. And now ( my code ) I have situation that my application wait to finish calculates, but when they are finished, my application still is running ( I wait on thread->wait ).

      Maybe when I quit event loop in second thread, this thread doesn't send finished() signal and I will wait in thread->wait() forever?

      I ask about it, not to solved a problem, but to understand how quit() works, and why I have to still wait on thread->wait

      1 Reply Last reply
      0
      • Q Offline
        Q Offline
        qwe3
        wrote on last edited by
        #4

        @JKSH The problem is QCoreApplication::processEvents();

        When I delete this line from my code - everything is ok. When this line is in my code - I wait in thread->wait() forever. Why?

        JonBJ 1 Reply Last reply
        0
        • Q qwe3

          @JKSH The problem is QCoreApplication::processEvents();

          When I delete this line from my code - everything is ok. When this line is in my code - I wait in thread->wait() forever. Why?

          JonBJ Online
          JonBJ Online
          JonB
          wrote on last edited by
          #5

          @qwe3
          Why is your calculation worker thread call processEvents() in the first place?
          It's probably hanging in that when the main UI thread has gone away/is no longer running the UI loop.

          1 Reply Last reply
          1
          • Q Offline
            Q Offline
            qwe3
            wrote on last edited by qwe3
            #6

            @JonB Using processEvents() doesn't make sense in my code. I tried something different and accidentally add this method. And now I would like to know, what's going on.

            Can you explain me what means It's probably hanging in that when the main UI thread has gone away/is no longer running the UI loop.?

            I know there is an event loop, which is in the main.cpp file:

            return a.exec();
            

            So when I close app and my code is in mainWindow's destructor I can't receive signals, because mainWindow is no longer in a.exec()?

            EDIT:

            I don't see link between processEvents() and It's probably hanging in that when the main UI thread has gone away/is no longer running the UI loop.

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

              This works fine for me:

              class Worker : public QObject
              {
              public:
                void calculate()
                {
                  QThread::sleep(20);
                  QCoreApplication::processEvents();
                }
              };
              
              class MainWindow : public QMainWindow
              {
                Q_OBJECT
              public:
                MainWindow()
                {
                  thread = new QThread(this);
                  worker = new Worker;
                  worker->moveToThread(thread);
                  thread->start();
                  QTimer::singleShot(0, worker, &Worker::calculate);
                }
                ~MainWindow()
                {
                  thread->quit();
                  thread->wait();
                }
              private:
                QThread *thread;
                Worker *worker;
              };
              
              int main(int argc, char **argv)
              {
                QApplication app(argc, argv);
                MainWindow mw;
                mw.show();
                return app.exec();
              }
              #include "main.moc"
              

              Please provide a minimal compilable example.

              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
              • Q Offline
                Q Offline
                qwe3
                wrote on last edited by qwe3
                #8

                @Christian-Ehrlicher Your code is ok?

                I think I can't add parent to

                worker = new Worker(this);
                

                I have error:

                QObject::moveToThread: Cannot move objects with a parent
                

                EDIT:
                When I delete parent I get the same situation: I wait on thread->wait()

                EDIT2:
                My code:

                int main(int argc, char *argv[])
                {
                    QApplication a(argc, argv);
                    MainWindow w;
                    w.show();
                    return a.exec();
                }
                
                MainWindow::MainWindow(QWidget *parent)
                    : QMainWindow(parent)
                    , ui(new Ui::MainWindow)
                {
                    ui->setupUi(this);
                
                    thread = new QThread(this);
                    worker = new Worker;
                    worker->moveToThread(thread);
                    thread->start();
                    QTimer::singleShot(0, worker, &Worker::calculate);
                }
                
                MainWindow::~MainWindow()
                {
                    thread->quit();
                
                    qInfo()<<"BEFORE WAIT";
                    thread->wait();
                    qInfo()<<"AFTER WAIT";
                
                    delete ui;
                }
                
                void Worker::calculate()
                {
                    QThread::sleep(20);
                    qInfo()<<"AFTER SLEEP";
                    QCoreApplication::processEvents();
                }
                
                Christian EhrlicherC 1 Reply Last reply
                0
                • Q qwe3

                  @Christian-Ehrlicher Your code is ok?

                  I think I can't add parent to

                  worker = new Worker(this);
                  

                  I have error:

                  QObject::moveToThread: Cannot move objects with a parent
                  

                  EDIT:
                  When I delete parent I get the same situation: I wait on thread->wait()

                  EDIT2:
                  My code:

                  int main(int argc, char *argv[])
                  {
                      QApplication a(argc, argv);
                      MainWindow w;
                      w.show();
                      return a.exec();
                  }
                  
                  MainWindow::MainWindow(QWidget *parent)
                      : QMainWindow(parent)
                      , ui(new Ui::MainWindow)
                  {
                      ui->setupUi(this);
                  
                      thread = new QThread(this);
                      worker = new Worker;
                      worker->moveToThread(thread);
                      thread->start();
                      QTimer::singleShot(0, worker, &Worker::calculate);
                  }
                  
                  MainWindow::~MainWindow()
                  {
                      thread->quit();
                  
                      qInfo()<<"BEFORE WAIT";
                      thread->wait();
                      qInfo()<<"AFTER WAIT";
                  
                      delete ui;
                  }
                  
                  void Worker::calculate()
                  {
                      QThread::sleep(20);
                      qInfo()<<"AFTER SLEEP";
                      QCoreApplication::processEvents();
                  }
                  
                  Christian EhrlicherC Offline
                  Christian EhrlicherC Offline
                  Christian Ehrlicher
                  Lifetime Qt Champion
                  wrote on last edited by Christian Ehrlicher
                  #9

                  @qwe3 said in Why QThread still working, when work is done?:

                  @Christian-Ehrlicher Your code is ok?

                  You're right, it was a slightly outdated version. Adjusted my code but still works fine.
                  Your code is not compilable at all so I can't test yours. Please provide a minimal compilable example similar to mine without any ui file or other unneeded stuff.

                  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
                  • Q Offline
                    Q Offline
                    qwe3
                    wrote on last edited by
                    #10
                    This post is deleted!
                    1 Reply Last reply
                    0
                    • Q Offline
                      Q Offline
                      qwe3
                      wrote on last edited by qwe3
                      #11

                      @Christian-Ehrlicher

                      Code:

                      #include <QApplication>
                      #include <QThread>
                      #include <QTimer>
                      #include <QMainWindow>
                      #include <QDebug>
                      class Worker : public QObject
                      {
                      public:
                        void calculate()
                        {
                          qInfo()<<"START SECOND THREAD";
                          QThread::sleep(20);
                          QCoreApplication::processEvents();
                          qInfo()<<"END SECOND THREAD";
                        }
                      };
                      
                      class MainWindow : public QMainWindow
                      {
                        Q_OBJECT
                      public:
                        MainWindow()
                        {
                          thread = new QThread(this);
                          worker = new Worker;
                          worker->moveToThread(thread);
                          thread->start();
                          QTimer::singleShot(0, worker, &Worker::calculate);
                        }
                        ~MainWindow()
                        {
                          thread->quit();
                          qInfo()<<"before";
                          thread->wait();
                          qInfo()<<"after";
                        }
                      private:
                        QThread *thread;
                        Worker *worker;
                      };
                      
                      int main(int argc, char **argv)
                      {
                        QApplication app(argc, argv);
                        MainWindow mw;
                        mw.show();
                        return app.exec();
                      }
                      #include "main.moc"
                      

                      I only add libraries and debuq. So I start app and after 5 second I close app using X button. Now I wait additional 15 seconds and see on debug END SECOND THREAD. And my app is still running. I have to close it in Qt Creator clicking red square. And have information:

                      21:03:25: The program has unexpectedly finished.
                      

                      I don't see on debug after

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

                        Works fine for me with Qt5.15 on linux but have the same effect on windows. Maybe it's worth opening a Qt bug report.

                        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
                        2
                        • Q Offline
                          Q Offline
                          qwe3
                          wrote on last edited by
                          #13

                          @Christian-Ehrlicher Thank you for help, but I don't understand this:

                          but have the same effect on windows
                          

                          Which option:

                          1. On linux everything is ok, but on windows you have the same problem like me
                          2. On linux and windows everything is ok

                          ?

                          jsulmJ 1 Reply Last reply
                          0
                          • Q qwe3

                            @Christian-Ehrlicher Thank you for help, but I don't understand this:

                            but have the same effect on windows
                            

                            Which option:

                            1. On linux everything is ok, but on windows you have the same problem like me
                            2. On linux and windows everything is ok

                            ?

                            jsulmJ Offline
                            jsulmJ Offline
                            jsulm
                            Lifetime Qt Champion
                            wrote on last edited by
                            #14

                            @qwe3 Since @Christian-Ehrlicher suggested to open a bug report it works on Linux but not on Windows (in case 2 there would not be any need to file a bug report).

                            https://forum.qt.io/topic/113070/qt-code-of-conduct

                            1 Reply Last reply
                            0
                            • Q Offline
                              Q Offline
                              qwe3
                              wrote on last edited by
                              #15

                              @jsulm I think the same, but I wanted to make sure :)

                              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