Deleting Qt Threads without crashing

July 27, 2012

I have an image processing application that needs to take advantage of multi-core processors, and as much parallelism efficiency as possible. So I wrote a worker thread class and a controlling class. The controlling class creates the worker threads, assigns them their jobs, then starts them. It then waits for all the workers to complete, deletes them, then moves on to the next phase of processing and repeats the cycle with new set of worker threads.

But my program would crash randomly. The entire processing job would take two hours on my 6 core machine, tens of thousands of threads would start and complete, and randomly it would all come crashing down. Sometimes a few minutes after start, sometimes an hour after.

This bug was frustrating. It turned out to be how and when I deleted the completed threads. I used the thread’s finished() signal to indicate that it was finished, and then deleted it. But it turns out this signal does not really mean finished. It means the code has returned from the run() call, but not all code is completed. Namely, a
mutex has not been released. So deleting the thread while that mutex was open, not a good thing. And deleteLater() did not make things better (did not investigate this).

So the fix is to use a new signal I created in the worker thread – completed() – that emits when the work is done, to tell my controller that the thread has done its job. Then I use the thread’s built in signal finshed() to call the thread deletion code:

This code checks the isFinished() method, which unlike the signal, does not return true until after the internal mutex is released. The call to wait() gives it chance to release that mutex before deletion. Now the program does not crash.

Entry filed under: Qt. Tags: .

Pitfalls of Qt Signals and Slots in embedded real-time systems


Archives