Exiting QThread



  • Hello,
    after creation of a thread I start it with the start() method like this:

    thread = new QThread(this);
    worker->moveToThread(thread);
    thread->start();
    

    If I understand it correctly, start() calls run() and exec() which starts an event loop. Later in the code I call:

    thread->wait();
    

    It ends the thread (isFinished() returns true). The documentations says that wait() returns when the thread returns from run(). But I never exited the thread, the event loop is still running, so how is it possible that the thread returns from run() and then wait() is returned?



  • hi @sykac said in Exiting QThread:

    Hello,
    after creation of a thread I start it with the start() method like this:

    thread = new QThread(this);
    worker->moveToThread(thread);
    thread->start();
    

    If I understand it correctly, start() calls run() and exec() which starts an event loop. Later in the code I call:

    thread->wait();
    

    It ends the thread (isFinished() returns true). The documentations says that wait() returns when the thread returns from run(). But I never exited the thread, the event loop is still running, so how is it possible that the thread returns from run() and then wait() is returned?

    I think
    you're supposed to call quit() and than wait ;-)

    myClass::~myClass(){
        thread->quit();
        thread->wait();
    }
    


  • @J-Hilk I tought that something like that should be called. But If I just call wait() without quit(), the thread stops anyway. And that's what I'm confused about. I don't know why is that possible.



  • @sykac,
    Hello!

    The thread will continue to run until quit is called. That stops the thread's event queue. If you are derive from QThread and override run you would have to process the event queue yourself. I do not reccomend this. You are doing the best method. I would add the following though:

    connect (thread, &QThread::finished, thread, &QThread::deleteLater);
    connect (thread, &QThread::started, worker, &Worker::initialize);
    connect (thread, &QThread::finished, worker, &Worker::complete);
    connect (thread, &QThread::finished, worker, &QThread::deleteLater);

    Here, initialize and complete are your slots that initialize and terminate thread specific items. Connecting to deleteLater allows you to avoid memory leaks by ensuring deletion of the objects once the thread is complete. You can then call thread ()->quit () from within your worker object when you reach that state which will cause the cascade of finished signals.

    In my worker objects (for threads of that nature), I typically monitor thread ()->isInterruptionRequested () and call requestInterruption (). This is a nice way to check if you need to stop busy work in a running object. It is really useful if you override the run method in a thread.

    If you are just trying to do a basic worker function (basically enter->do soimething->leave) I suggest you use QFuture and QFutureWatcher and start your thread with QtConcurrent::run (...). This is a very effective for worker objects whereas the other way is really effective for asynchronous objects like communications handlers.

    For more information on QThread techniques see Maya's blog: https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/


Log in to reply
 

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