Unsolved Exiting QThread
-
Hello,
after creation of a thread I start it with thestart()
method like this:thread = new QThread(this); worker->moveToThread(thread); thread->start();
If I understand it correctly,
start()
callsrun()
andexec()
which starts an event loop. Later in the code I call:thread->wait();
It ends the thread (
isFinished()
returns true). The documentations says thatwait()
returns when the thread returns fromrun()
. But I never exited the thread, the event loop is still running, so how is it possible that the thread returns fromrun()
and thenwait()
is returned? -
hi @sykac said in Exiting QThread:
Hello,
after creation of a thread I start it with thestart()
method like this:thread = new QThread(this); worker->moveToThread(thread); thread->start();
If I understand it correctly,
start()
callsrun()
andexec()
which starts an event loop. Later in the code I call:thread->wait();
It ends the thread (
isFinished()
returns true). The documentations says thatwait()
returns when the thread returns fromrun()
. But I never exited the thread, the event loop is still running, so how is it possible that the thread returns fromrun()
and thenwait()
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()
withoutquit()
, 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/