QRunnable Finishes, activeThreadCount() Does Not Decrement
-
I have an application that creates many QRunnable's, often at the rate of ~50 Hz. I start them using:
QThreadPool::globalInstance()->start(myRunnable);
Each of these runnables then handles their small, individual task and finishes. Under normal circumstances, when I monitor the active thread count by:
qDebug() << "Active thread count = " << QThreadPool::globalInstance()->activeThreadCount();
... I see everything is working well, and will see a count rise and fall.
Lately, though, when I'm running this on a Windows 10 PC (Qt 5.15.2) I have started to see things go "off the rails". This was first noticed by fast-elevating memory usage to the point that the application would crash (error: "terminate called after throwing an instance of 'std::bad_alloc'").
Now, looking more closely at the active thread count (using the method above), I can see that when things turn bad the activeThreadCount() stops decrementing. I have added more debug statements and can see that this is occurring despite the destructors for each QRunnable object firing. So, in a nutshell, the runnable is starting and appears to be finishing (calling its destructor) ... but as far as QThreadPool::globalInstance() is concerned, the thread is still active. It seems logical that this would cause memory use to explode.
Any ideas as to what may be causing this? Thanks.
-
Make sure you're cleaning up all the memory from you
QRunnable
s.The thread count shouldn't decrease, as the threads are pooled, so in that regard the Qt code is doing the right thing. Starting threads is expensive (especially on Linux), and the global pool uses the "ideal count". You should notice also that running more jobs does not increase the number of threads (nor does it stop the existing ones).
-
Make sure you're cleaning up all the memory from you
QRunnable
s.The thread count shouldn't decrease, as the threads are pooled, so in that regard the Qt code is doing the right thing. Starting threads is expensive (especially on Linux), and the global pool uses the "ideal count". You should notice also that running more jobs does not increase the number of threads (nor does it stop the existing ones).
@kshegunov Thanks for your response. I agree and am seeing the behavior as you describe ... up to and including the "ideal" count. I am normally seeing activeThreadCount() decreasing below this ideal count as each QRunnable (successfully) completes, meaning I'm staying ahead of the game. It's during this occasional, anomalous behavior that I see that it does not.
As each QRunnable is performing its own computation to solve its piece of a bigger task, I am suspecting that there may be something periodically hanging up and sinking one or more of these jobs, leading to a build-up/traffic jam behind it. That I have not seen this on a RHEL box running the same code is a bit puzzling, however.