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 917 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