Will code after a call to QThread::exit() ever get executed?



  • I am working on legacy code that has a class, say FooBarThread, that extends from QThread and has the following method which puzzles me:

    void FooBarThread::mpStop(void)
    {
       exit();
        if (isRunning())
        {
            if (!wait(15000))
                terminate();
        }
    }
    

    Looking at the QThread documentation (Qt 4.8), for the exit() method, I read

    "Note that unlike the C library function of the same name, this function does return to the caller -- it is event processing that stops."

    so from this, I understand that after the call to exit(), the function immediately returns to the caller. My educated guess therefore is that everything that comes after this exit() call is 100% sure to be never executed and can safely be removed. Am I right with my conclusion?



  • No, your FooBarThread is the caller! So when the FooBarThread calls the exit function it will return to FooBarThread.
    Only the eventHandler inside that QThread is stopped an thus issuing a signal below that exit will have no effect. The code after the exit is ambiguous. You just called exit to the Thread, so what will isRunning return? Will isRunning check the eventLoop status or something else?
    And why wait 15000 before terminate? Because it is a QThread it might be best to call deleteLater on it and have it cleaned up later by the qApp evenLoop.



  • @Jeroentjehome said:

    [...] The code after the exit is ambiguous. You just called exit to the Thread, so what will isRunning return? Will isRunning check the eventLoop status or something else?

    To be honest, I have no idea... The Qt documentation for QThread::isRunning() says "Returns true if the thread is running; otherwise returns false." I'm not sure if that has anything to do with the event loop and QThread::exit()... if anybody can shed a light on this, feel free...

    And why wait 15000 before terminate? Because it is a QThread it might be best to call deleteLater on it and have it cleaned up later by the qApp evenLoop.

    I have no idea why the code after the exit() call is like it is now. I have not written it :-) It is legacy code from about 10 years ago, which I'm now trying to understand and improve. I have not that much experience with QThreads and deleteLater... do you mean I can replace the whole method with something like this:

    void FooBarThread::mpStop(void)
    {
       exit();
       deleteLater();
    }
    

    (sorry if the last is a rather stupid question, but I currently don't have much time to read up on everything that has to do with QThread... some day I'll get to it ;-)



  • What might be the best solution is to have a signal/slot connection with the QThread object. So when exit() is called, it will emit the stopped signal and in your controlling class (the class that creates the QThread and is the parent) is able to call deleteLater on it. That way you know for sure the QThread is stopped nicely and cleaned up without your program crashing because your parent class tries to access its child QThread object.
    Here is a very clear doc of how you might want to utilize QThread.
    https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/
    Everything that controls the QThread object is placed in a Control object and the QThread is placed in the worker class.
    So if it is really legacy code, do it properly this time around ;-)


  • Lifetime Qt Champion

    Hi,

    If I may, the current documentation of QThread describes all available techniques with their pros and cons


  • Moderators

    @Bart_Vandewoestyne said:

    The Qt documentation for QThread::isRunning() says "Returns true if the thread is running; otherwise returns false." I'm not sure if that has anything to do with the event loop and QThread::exit()... if anybody can shed a light on this, feel free...

    QThread::isRunning() returns true while the code inside QThread::run() is still running.

    Does FooBarThread::run() start an event loop? If it doesn't, then QThread::exit() does absolutely nothing.

    @Bart_Vandewoestyne said:

    do you mean I can replace the whole method with something like this:

    void FooBarThread::mpStop(void)
    {
       exit();
       deleteLater();
    }
    

    We need more info before we can give you a "yes"/"no" answer:

    1. Who calls FooBarThread::mpStop()? Which thread does FooBarThread::mpStop() run in?
    2. What does FooBarThread::run() do?
    3. Is your FooBarThread created on the stack or the heap?

    But in general, I don't recommend deleting a QThread from inside a QThread's own method.

    @Jeroentjehome said:

    What might be the best solution is to have a signal/slot connection with the QThread object.
    ...
    So if it is really legacy code, do it properly this time around ;-)

    You are asking the OP to completely redesign this mysterious part of an old piece of software, without understand how it behaved before. Are you sure this is wise?

    @Jeroentjehome said:

    Here is a very clear doc of how you might want to utilize QThread.
    https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/

    Please be aware that Maya's article only tells half the story. If you want to run a custom infinite loop and don't need event-driven code, then the best approach is to subclass QThread.



  • He,
    If you don't do a real good update now, it will bite you in the ass later on! Count on it!!
    Since he stops the running thread, it is a program with an finite loop, not as you mentioned that maya is not totally right. Otherwise check out the QThreadPool stuff for higher level QThread control.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.