I have a lot of long running tasks that run in the background of my Python app. I put them all in the global QThreadPool
. When the user quits, all of those background tasks need to stop.
Right now, I have the following code:
app.aboutToQuit.connect(killAllThreads)
def killAllThreads():
QtCore.QThreadPool.globalInstance().waitForDone()
I've seen suggestions to add a global variable that says whether the application should be quitting, and to have threads terminate themselves, but this sounds like a terribly messy and inelegant solution. Would you really propose adding a check before every line of code in a background task to make sure that the application shouldn't be quitting yet? That's hundreds of checks that I would have to add.
The suggestion seems to make the assumption that my tasks are simple and/or have complex clean ups involved, but actually, I have just the opposite: the tasks involve hundreds of lines of code, each of which can take several seconds, but no clean up needs to be done at all.
I've heard simply killing the threads would be a bad idea, as then they wouldn't be guaranteed to clean up properly, but as no clean up is necessary, that's exactly what I want to do. Additionally, race conditions could occur, but again, the tasks need to stop right now, so I really don't care if they end up in an invalid state.
So I need to know the following:
- How do I get a list of all the running threads in a
QThreadPool
? - How do I have them abort what they're doing?
The simple answer to this question is that you cannot abort any of the threads in QThreadPool, because they are wrapped in instances of QRunnable. There is no external way to terminate a QRunnable; it has to terminate itself from inside its reimplemented
run()
method.However, it sounds like the tasks running inside your
run()
method don't lend themselves to periodically checking a flag to see if they should terminate.If that is the case, you only have two options:
Obviously, choosing (2) implies switching to a more low-level solution, like QThread, and managing the pool of threads yourself.
use daemons, they are automatically terminated when the main thread is ended