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. Terminate QThread correctly

Terminate QThread correctly

Scheduled Pinned Locked Moved Unsolved General and Desktop
threadqt4.8yocto dizzy
11 Posts 7 Posters 18.4k Views
  • 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.
  • mrjjM Offline
    mrjjM Offline
    mrjj
    Lifetime Qt Champion
    wrote on last edited by
    #2

    Hi
    How do you call
    ThreadWorker::onAbort() ?

    if not via signal & slot then you might need to wrap
    thread_exit in a std::atomic<bool> to avoid race conditions.

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

      Hi,

      If you have an infinite loop, you should rather have a stop method that allows you to exit the loop cleanly. Terminating threads is never a good idea and should only be a last resort solution.

      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
      3
      • mrjjM mrjj

        Hi
        How do you call
        ThreadWorker::onAbort() ?

        if not via signal & slot then you might need to wrap
        thread_exit in a std::atomic<bool> to avoid race conditions.

        A Offline
        A Offline
        Andrea
        wrote on last edited by Andrea
        #4

        @mrjj the onAbort() slot is called via signal, with QueuedConnection, since the emitter and receiver live in different threads.
        @SGaist there is not a "stop" method, but the "onAbort()" method does same logical operation: it just sets the bool condition checked in the loop to exit from this latter one. Maybe I could be wrong, but to me it seems this is a clean way to exit thread loop, isn't it?
        Mmm..but when I'm going to close the application, terminate a thread seems to be a good way to follow before closing the whole application or should I just close the application a let the OS "manage" threads created? Thanks

        jsulmJ 1 Reply Last reply
        0
        • A Andrea

          @mrjj the onAbort() slot is called via signal, with QueuedConnection, since the emitter and receiver live in different threads.
          @SGaist there is not a "stop" method, but the "onAbort()" method does same logical operation: it just sets the bool condition checked in the loop to exit from this latter one. Maybe I could be wrong, but to me it seems this is a clean way to exit thread loop, isn't it?
          Mmm..but when I'm going to close the application, terminate a thread seems to be a good way to follow before closing the whole application or should I just close the application a let the OS "manage" threads created? Thanks

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

          @Andrea After calling onAbort() do you actually wait for the threads to finish? See http://doc.qt.io/qt-5.9/qthread.html#wait

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

          A 1 Reply Last reply
          0
          • A Andrea

            Hi everybody,

            I've a doubt about how to correctly close a QThread.
            I've read the QThread Basics docs and also had a look on StarckOverflow and the Qt forum, but still having the doubt.

            I've implemented many htread-worker threads, and they all work correctly. The only problem is when I delete the thread: I always get "QThread: destroyed while thread is still running".
            Putting a "wait()" call after the "terminate()" one, never exit since it remains pending waiting for the thread termination.

            Here a bit of my code:

            /*   THIS IS THE CREATION OF THE THREAD CONTROLLER AND THE WORKER */
            QThread *threadController = new QThread(this);
            
            //	ThreadWorker is my custom class
            ThreadWorker* threadWorker = new ThreadWorker(  );
            threadWorker->moveToThread( threadController );
            
            connect( threadController , SIGNAL(started()), threadWorker, SLOT(Work()), Qt::QueuedConnection );
            
            threadController ->start();
            
            

            Here the implementation of the custom class

            /*   ThreadWorker.h  */
            class ThreadWorker : public QObject
            {
                Q_OBJECT
            
            public:
                ThreadWorker();
                ~ThreadWorker();
            
            public slots:
                void Work();
                void onAbort();
            
            private:
                bool thread_exit;
            };
            
            
            /*   ThreadWorker.cpp    */
            //	Constructor
            ThreadWorker::ThreadWorker()
            {
                this->thread_exit = false;
            }
            
            //	Destructor
            ThreadWorker::~ThreadWorker()
            {
            }
            
            //	"Main" function
            void ThreadWorker::Work() 
            {
            	//	Thread loop
            	while( !this->thread_exit )
            	{
            		//  Wait
            		sleep(1);
            
            		//	Do some actions..
            
            		//  Process application events
            		QCoreApplication::processEvents( QEventLoop::AllEvents );
            	}
            }
            
            //	Stop thread
            void ThreadWorker::onAbort()
            {
            	//  Exit thread loop
            	this->thread_exit = true;
            }
            

            I'm using Qt 4.8 on a iMX6SX board with Yocto Dizzy distro.

            Many thanks
            Andrea

            J.HilkJ Offline
            J.HilkJ Offline
            J.Hilk
            Moderators
            wrote on last edited by
            #6

            @Andrea

            Usually you call quit to quit a thread:
            Try this.

            connect(qApp, &QApplication::aboutToQuit,   threadController, [=]{
                threadController->quit();
                threadController->wait();
            });
            

            Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


            Q: What's that?
            A: It's blue light.
            Q: What does it do?
            A: It turns blue.

            1 Reply Last reply
            2
            • jsulmJ jsulm

              @Andrea After calling onAbort() do you actually wait for the threads to finish? See http://doc.qt.io/qt-5.9/qthread.html#wait

              A Offline
              A Offline
              Andrea
              wrote on last edited by
              #7

              @jsulm if I put a wait() after "calling" onAbort() method (via signal-slot), hte program hang waiting the thread to finish...but this never happens. I'm sure the thread exits its while loop (I've used qDebug() to check this), but calling wait function of thread controller never returns.

              J.HilkJ 1 Reply Last reply
              0
              • A Andrea

                @jsulm if I put a wait() after "calling" onAbort() method (via signal-slot), hte program hang waiting the thread to finish...but this never happens. I'm sure the thread exits its while loop (I've used qDebug() to check this), but calling wait function of thread controller never returns.

                J.HilkJ Offline
                J.HilkJ Offline
                J.Hilk
                Moderators
                wrote on last edited by
                #8

                @Andrea
                wait() will return when either of these 2 conditions are met:

                • The thread associated with this QThread object has finished execution (i.e. when it returns from run()). This function will return true if the thread has finished. It also returns true if the thread has not been started yet.
                • time milliseconds has elapsed. If time is ULONG_MAX (the default), then the wait will never timeout (the thread must return from run()). This function will return false if the wait timed out.

                the default time is ULONG_MAX which is 4294967295 ms -> roughly 50 days

                you never call quit on threadController, onAbort only effects your worker object, not the thread wrapper.


                Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                Q: What's that?
                A: It's blue light.
                Q: What does it do?
                A: It turns blue.

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

                  Sorry, I missed the implementation of onAbort while looking at the code.

                  Note that that name is a bit confusing. It rather sounds like something that would be called when the thread has aborted.

                  IIRC, boolean variable used like that might be "optimised". I'd replace it with a QAtomicInt.

                  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
                  0
                  • A Andrea

                    Hi everybody,

                    I've a doubt about how to correctly close a QThread.
                    I've read the QThread Basics docs and also had a look on StarckOverflow and the Qt forum, but still having the doubt.

                    I've implemented many htread-worker threads, and they all work correctly. The only problem is when I delete the thread: I always get "QThread: destroyed while thread is still running".
                    Putting a "wait()" call after the "terminate()" one, never exit since it remains pending waiting for the thread termination.

                    Here a bit of my code:

                    /*   THIS IS THE CREATION OF THE THREAD CONTROLLER AND THE WORKER */
                    QThread *threadController = new QThread(this);
                    
                    //	ThreadWorker is my custom class
                    ThreadWorker* threadWorker = new ThreadWorker(  );
                    threadWorker->moveToThread( threadController );
                    
                    connect( threadController , SIGNAL(started()), threadWorker, SLOT(Work()), Qt::QueuedConnection );
                    
                    threadController ->start();
                    
                    

                    Here the implementation of the custom class

                    /*   ThreadWorker.h  */
                    class ThreadWorker : public QObject
                    {
                        Q_OBJECT
                    
                    public:
                        ThreadWorker();
                        ~ThreadWorker();
                    
                    public slots:
                        void Work();
                        void onAbort();
                    
                    private:
                        bool thread_exit;
                    };
                    
                    
                    /*   ThreadWorker.cpp    */
                    //	Constructor
                    ThreadWorker::ThreadWorker()
                    {
                        this->thread_exit = false;
                    }
                    
                    //	Destructor
                    ThreadWorker::~ThreadWorker()
                    {
                    }
                    
                    //	"Main" function
                    void ThreadWorker::Work() 
                    {
                    	//	Thread loop
                    	while( !this->thread_exit )
                    	{
                    		//  Wait
                    		sleep(1);
                    
                    		//	Do some actions..
                    
                    		//  Process application events
                    		QCoreApplication::processEvents( QEventLoop::AllEvents );
                    	}
                    }
                    
                    //	Stop thread
                    void ThreadWorker::onAbort()
                    {
                    	//  Exit thread loop
                    	this->thread_exit = true;
                    }
                    

                    I'm using Qt 4.8 on a iMX6SX board with Yocto Dizzy distro.

                    Many thanks
                    Andrea

                    JKSHJ Offline
                    JKSHJ Offline
                    JKSH
                    Moderators
                    wrote on last edited by
                    #10

                    @Andrea said in Terminate QThread correctly:

                    @jsulm if I put a wait() after "calling" onAbort() method (via signal-slot), hte program hang waiting the thread to finish...but this never happens. I'm sure the thread exits its while loop (I've used qDebug() to check this), but calling wait function of thread controller never returns.

                    Hi @Andrea,

                    You stopped the loop in ThreadWorker, but you didn't stop the loop in QThread.

                    As @J-Hilk said, you need to call threadController->quit() too.

                    @Andrea said in Terminate QThread correctly:

                    I've read the QThread Basics docs and also had a look on StarckOverflow and the Qt forum, but still having the doubt.

                    Also read through http://doc.qt.io/qt-5/qthread.html#details and http://doc.qt.io/qt-5/threads-technologies.html. There are 2 ways to use QThread:

                    1. Create a worker object
                    2. Subclass QThread and override QThread::run().

                    If you want your thread to receive signals, you should use a worker object. However, if you want to run an infinite loop (while( !this->thread_exit ) { /*...*/ }) and you don't need signals/slots, then it's simpler to subclass QThread.

                    Judging by your code example, I don't think you need a worker object. Also, if you subclass QThread, the thread will quit when your while loop stops.

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

                    1 Reply Last reply
                    2
                    • BuckwheatB Offline
                      BuckwheatB Offline
                      Buckwheat
                      wrote on last edited by
                      #11

                      Hi @Andrea

                      WOW! Infinite loop to just sleep and process events. Why not just start a timer of PreciseTimer and allow the events to flow freely in the thread? Since you want it to run as fast as possible you can even set the timeout to 0 to run freely when there are no events.

                      You can then look at thread->requestInterruption () and the thread will comply! Just make sure if you are doing something in a loop in the timer callback you check thread ()->isInterruptionRequested (). And best of all... NO CHECKING THE EVENT QUEUE!

                      There is a nice writeup about proper thread use at: https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/

                      You are basically there with your code. Just the loop is wasteful.

                      Dave Fileccia

                      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