[Interest] How to properly terminate QtConcurrent run

Elvis Stansvik elvstone at gmail.com
Tue Aug 16 22:31:22 CEST 2022


Den tis 16 aug. 2022 kl 18:23 skrev Sean Murphy via Interest
<interest at qt-project.org>:
>
> I've encountered a bug of mine, that is leading me to ask how to properly fix some behavior...
>
> The setup: I've got a worker task that runs in a separate thread, waiting for jobs to come over from MainWindow. When that worker task gets a job, it splits the jobs into smaller chunks, and then uses QtConcurrent::map() to process those chunks in parallel. Currently I've got a bug in my processChunk() function which is causing an infinite loop (I'm fixing that as we speak), but what I noticed is that because of those infinite loops running inside of QtConcurrent calls, I was unable to quit my application. Since all the infinite loop is happening in a non-UI thread, the UI is responsive and I can choose to quit the application from either the File menu or the 'X' button. The UI goes away, but the application is still running, and there's no way to do anything about it other than killing it out at the OS task manager level. What I want to have happen is any processing that is in process when the user quits is immediately aborted/terminated and the application exits cleanly.
>
> So basically I have:
>  - a thread, workerThread
>  - an object, workerObject, that lives in workerThread
>  - a function, workerObject::processChunk()
>     - this function is the one that currently has an infinite loop bug
>  - a future watcher, chunkWatcher
>
> And then when workerObject receives a new request signal from MainWindow, it calls
>   chunkWatcher->setFuture(QtConcurrent::map(chunks, processChunk));
>
> In MainWindow, I've got this:
> ~MainWindow()
> {
>   mWorkerThread->terminate();
>   mWorkerThread ->wait();
> }
>
> But that code only kills the thread the worker task itself is in, not the threads that QtConcurrent has spawned off to run processChunk() that will never return. I'm poking through the QFutureWatcher, but I don't see a way to forcefully terminate stuff that's in progress. All I see is cancel() and pause(), but if I understand what I'm seeing, those don't seem to stop processChunk() calls that are already in progress, they just prevent processChunk() from being called on the remaining chunks after each chunk in progress finished.
>
> So is there any way I can terminate QtConcurrent::map()?

You should signal processChunk to stop processing early. You can for
example do this through an atomic variable which is periodically
checked, e.g. as part of the stop condition in that loop you
mentioned.

I may be wrong, but I think terminating a thread forcefully is
considered a poor design.

Elvis

>
> Sean
>
>
>
>
>
>
> This e-mail, including any attached files, may contain confidential information, privileged information and/or trade secrets for the sole use of the intended recipient. Any review, use, distribution, or disclosure by others is strictly prohibited. If you are not the intended recipient (or authorized to receive information for the intended recipient), please contact the sender by reply e-mail and delete all copies of this message.
> _______________________________________________
> Interest mailing list
> Interest at qt-project.org
> https://lists.qt-project.org/listinfo/interest


More information about the Interest mailing list