If I have a Qt application (that uses QCoreApplication
), and this application starts a few permanent threads, what is the proper way to shut down the application?
Is it alright to just run QCoreApplication::quit()
in one of the threads? Will this cause the other threads to be gracefully terminated (and have all their contained objects' destructors called, as opposed to being forcefully killed)?
Further details to explain the nature of the threads: they are predefined and run from startup and do not stop until the application exits, i.e. they're permanent. They run their own event loop and communicate with other threads via signals and slots. These are normal threading, not task-based concurrency.
Most long running 'thread main' functions have a form a bit like the following:
while (doWork) {
work();
}
with doWork being a std::atomic<bool>
.
When the main thread wants to quit, it sets myThread.doWork = false
on all the threads that are still alive, which allows them to fall out when they're ready.
By calling myThread.wait()
on the main thread, it blocks until the thread that you've told to stop doing work actually stops.
In doing this for all your threads, by the time the main thread leaves main() it's the only thread still running.
Side note: if you have to await work to be pushed to it, you probably want to look into the QWaitCondition class so that you can awake your thread both when there's work and when you want it to stop.
It highly depends on how you use the threads.
If you use them as seperate eventloops, and not as "worker threads", simply stop the by quitting the threads from the QCoreApplication::aboutToQuit
signal:
QObject::connect(qApp, &QCoreApplication::aboutToQuit, thread, [thread](){
thread->quit();
thread->wait(1000);
});
(For multiple threads, first quit all of them and then wait)
In case you use them as real workerthreads, where you do permanent work in a loop etc, you can use QThreads interruptions mechanism. In your thread do:
while(!QThread::currentThread()->isInterruptionRequested()) {
// code...
}
and quit them in a very similar way:
QObject::connect(qApp, &QCoreApplication::aboutToQuit, thread, [thread](){
thread->requestInterruption();
thread->wait(1000);
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With