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. terminating a thread
Forum Updated to NodeBB v4.3 + New Features

terminating a thread

Scheduled Pinned Locked Moved Solved General and Desktop
16 Posts 3 Posters 2.5k Views 3 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.
  • mzimmersM Offline
    mzimmersM Offline
    mzimmers
    wrote on last edited by
    #5

    Interesting. So, MyThread::stop would be a slot to receive the signal from the display widget? Would MyThread::run then send a signal to the QApplication prior to exiting? And if so, is there concern for a race condition under which the Application might try to exit before the thread has terminated?

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

      No there's no signal emitted since you implement your own version of run. Note that you can send a signal yourself if you need/want to. The call to wait after the call to stop is where you ensure that your thread stops before you continue with your application.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      mzimmersM 1 Reply Last reply
      1
      • SGaistS SGaist

        No there's no signal emitted since you implement your own version of run. Note that you can send a signal yourself if you need/want to. The call to wait after the call to stop is where you ensure that your thread stops before you continue with your application.

        mzimmersM Offline
        mzimmersM Offline
        mzimmers
        wrote on last edited by
        #7

        @SGaist OK, I understand the mechanics of the worker thread, but how to invoke the wait is a bit of a mystery. Here's my main:

        int main(int argc, char *argv[])
        {
            QApplication a(argc, argv);
            Widget widget;
            Worker worker;
        
            QObject::connect(&worker, &Worker::newResponseText, &widget, &Widget::addText);
            QObject::connect(&widget, &Widget::quitButtonPushed, &worker, &Worker::doQuit);
        
            widget.show();
            worker.start();
            return a.exec();
        }
        

        I don't see:

        • where to put the wait(), given that a.exec() runs infinitely.
        • how to terminate the application (worker::run() could send a signal after it exits its loop, I suppose).
        kshegunovK 1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #8

          You could use a lambda that calls doQuit and then wait rather than than connecting doQuit directly. Or you can integrate wait in doQuit.

          Add a signal to your Worker class that you emit at the end of the loop.

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          mzimmersM 1 Reply Last reply
          0
          • mzimmersM mzimmers

            @SGaist OK, I understand the mechanics of the worker thread, but how to invoke the wait is a bit of a mystery. Here's my main:

            int main(int argc, char *argv[])
            {
                QApplication a(argc, argv);
                Widget widget;
                Worker worker;
            
                QObject::connect(&worker, &Worker::newResponseText, &widget, &Widget::addText);
                QObject::connect(&widget, &Widget::quitButtonPushed, &worker, &Worker::doQuit);
            
                widget.show();
                worker.start();
                return a.exec();
            }
            

            I don't see:

            • where to put the wait(), given that a.exec() runs infinitely.
            • how to terminate the application (worker::run() could send a signal after it exits its loop, I suppose).
            kshegunovK Offline
            kshegunovK Offline
            kshegunov
            Moderators
            wrote on last edited by kshegunov
            #9

            @mzimmers said in terminating a thread:

            int main(int argc, char *argv[])
            {
                QApplication a(argc, argv);
                Widget widget;
                Worker worker;
            
                QObject::connect(&worker, &Worker::newResponseText, &widget, &Widget::addText);
            
                // Invoke directly as there's no running event loop to process the slot
                QObject::connect(&widget, &Widget::quitButtonPushed, &worker, &Worker::doQuit, Qt::DirectConnection);
                // Connect the aboutToQuit from the `QCoreApplication` so you don't hang when the button's not pressed
                QObject::connect(&a, &QCoreApplication::aboutToQuit, &worker, &Worker::doQuit, Qt::DirectConnection);
            
               widget.show();
               worker.start();
            
                // Store the return value and then wait for the thread to exit
                int retValue = QApplication::exec();
                worker.wait();
                // After the thread has finished, return from main()
                return retValue;
            }
            

            This is all assuming doQuit is what @SGaist wrote - raising an atomic flag to tell the thread to quit.

            Btw, you can use QThread::requestInterruption and QThread::isInterruptionRequested instead of rolling your own.

            Read and abide by the Qt Code of Conduct

            mzimmersM 1 Reply Last reply
            4
            • SGaistS SGaist

              You could use a lambda that calls doQuit and then wait rather than than connecting doQuit directly. Or you can integrate wait in doQuit.

              Add a signal to your Worker class that you emit at the end of the loop.

              mzimmersM Offline
              mzimmersM Offline
              mzimmers
              wrote on last edited by
              #10

              @SGaist so my worker thread will signal the QApplication, so that the QApplication can quit. Correct?

              I'm still lost regarding the use of wait(). It can't reside in the worker object, as a thread can't wait for itself. And I have no context from which to use it in main(). Do I need a parent class/object for my worker?

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

                See @kshegunov's excellent alternative.

                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
                1
                • kshegunovK kshegunov

                  @mzimmers said in terminating a thread:

                  int main(int argc, char *argv[])
                  {
                      QApplication a(argc, argv);
                      Widget widget;
                      Worker worker;
                  
                      QObject::connect(&worker, &Worker::newResponseText, &widget, &Widget::addText);
                  
                      // Invoke directly as there's no running event loop to process the slot
                      QObject::connect(&widget, &Widget::quitButtonPushed, &worker, &Worker::doQuit, Qt::DirectConnection);
                      // Connect the aboutToQuit from the `QCoreApplication` so you don't hang when the button's not pressed
                      QObject::connect(&a, &QCoreApplication::aboutToQuit, &worker, &Worker::doQuit, Qt::DirectConnection);
                  
                     widget.show();
                     worker.start();
                  
                      // Store the return value and then wait for the thread to exit
                      int retValue = QApplication::exec();
                      worker.wait();
                      // After the thread has finished, return from main()
                      return retValue;
                  }
                  

                  This is all assuming doQuit is what @SGaist wrote - raising an atomic flag to tell the thread to quit.

                  Btw, you can use QThread::requestInterruption and QThread::isInterruptionRequested instead of rolling your own.

                  mzimmersM Offline
                  mzimmersM Offline
                  mzimmers
                  wrote on last edited by
                  #12

                  @kshegunov so, do I correctly understand that, in your example, the QApplication will terminate before the worker thread?

                  I didn't know you could do that...

                  kshegunovK 1 Reply Last reply
                  0
                  • mzimmersM mzimmers

                    @kshegunov so, do I correctly understand that, in your example, the QApplication will terminate before the worker thread?

                    I didn't know you could do that...

                    kshegunovK Offline
                    kshegunovK Offline
                    kshegunov
                    Moderators
                    wrote on last edited by kshegunov
                    #13

                    You can exit the (main) event loop at any time you want, you need to wait before returning from main() so your process doesn't terminate before the thread has done so. So yes, you can exit the loop before returning from main(). :)

                    PS.
                    QCoreApplication::exec does practically nothing, it's a convenience function, you can substitute it with:

                    QEventLoop loop;
                    return loop.exec();
                    

                    Read and abide by the Qt Code of Conduct

                    mzimmersM 1 Reply Last reply
                    3
                    • kshegunovK kshegunov

                      You can exit the (main) event loop at any time you want, you need to wait before returning from main() so your process doesn't terminate before the thread has done so. So yes, you can exit the loop before returning from main(). :)

                      PS.
                      QCoreApplication::exec does practically nothing, it's a convenience function, you can substitute it with:

                      QEventLoop loop;
                      return loop.exec();
                      
                      mzimmersM Offline
                      mzimmersM Offline
                      mzimmers
                      wrote on last edited by
                      #14

                      @kshegunov well, isn't that something. Very nice.

                      I implemented it a bit differently from your example:

                      int main(int argc, char *argv[])
                      {
                          QApplication a(argc, argv);
                          Widget widget;
                          Worker worker;
                          int rc;
                      
                          QObject::connect(&worker, &Worker::newResponse, &widget, &Widget::addText);
                          QObject::connect(&widget, &Widget::quitButtonPushed, &worker, &Worker::doQuit);
                          QObject::connect(&worker, &Worker::reachedEndOfThread, &a, &QApplication::exit);
                      
                          widget.show();
                          worker.start();
                          rc = a.exec();
                          worker.wait();
                          return rc;
                      }
                      
                      Seems to work fine. Thanks, guys.
                      
                      kshegunovK 1 Reply Last reply
                      0
                      • mzimmersM mzimmers

                        @kshegunov well, isn't that something. Very nice.

                        I implemented it a bit differently from your example:

                        int main(int argc, char *argv[])
                        {
                            QApplication a(argc, argv);
                            Widget widget;
                            Worker worker;
                            int rc;
                        
                            QObject::connect(&worker, &Worker::newResponse, &widget, &Widget::addText);
                            QObject::connect(&widget, &Widget::quitButtonPushed, &worker, &Worker::doQuit);
                            QObject::connect(&worker, &Worker::reachedEndOfThread, &a, &QApplication::exit);
                        
                            widget.show();
                            worker.start();
                            rc = a.exec();
                            worker.wait();
                            return rc;
                        }
                        
                        Seems to work fine. Thanks, guys.
                        
                        kshegunovK Offline
                        kshegunovK Offline
                        kshegunov
                        Moderators
                        wrote on last edited by
                        #15

                        You should still connect the aboutToQuit signal, as you may click the x in the top right of the window, which wouldn't trigger your doQuit.

                        Read and abide by the Qt Code of Conduct

                        1 Reply Last reply
                        2
                        • mzimmersM Offline
                          mzimmersM Offline
                          mzimmers
                          wrote on last edited by
                          #16

                          Done. Thanks again.

                          1 Reply Last reply
                          1

                          • Login

                          • Login or register to search.
                          • First post
                            Last post
                          0
                          • Categories
                          • Recent
                          • Tags
                          • Popular
                          • Users
                          • Groups
                          • Search
                          • Get Qt Extensions
                          • Unsolved