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.
  • 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