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?

Why QThread still working, when work is done?

Scheduled Pinned Locked Moved Unsolved General and Desktop
15 Posts 5 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.
  • Q Offline
    Q Offline
    qwe3
    wrote on last edited by
    #1

    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 1 Reply Last reply
    0
    • 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 Offline
            JonBJ Offline
            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 Online
                Christian EhrlicherC Online
                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 Online
                    Christian EhrlicherC Online
                    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 Online
                          Christian EhrlicherC Online
                          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