PDA

View Full Version : QFutureWatcher and "cancel" on a QtConcurrent filter...



t_3
9th February 2015, 08:13
... is it save to replace the future of a watcher right after calling "cancel" on the watcher?

i.e.:

m_watcher.cancel();

ProcessWrapper process;
m_watcher.setFuture(QtConcurrent::filter(m_cacheQu eue, process));

i have no particular use for the future returned by the concurrent filter, so i just simply set it to the watcher; also i don't connect the watcher signals, which only purpose is to cancel processing and immediately start processing a new sequence; the docs say that cancel is async, what'd be the preferred way in this case as i don't want to wait for the (now obsolete) previous processing results. i just wonder what happens internally if i do this that way ;) from the outside it looks ok, and everything seems to work as expected...

wysota
9th February 2015, 08:18
You can cancel a future directly, you don't need a watcher for this.

t_3
11th February 2015, 04:07
You can cancel a future directly, you don't need a watcher for this.
thanks!

i forgot to add that i also decided to use a watcher because this seems to be the easiest way to also have throttling - so the original question remains.
if the method above (call cancel on the watcher and immediately set a new future) could cause problems, i'll probably drop the watcher, and implement throttling by a QSemaphore. another way would be to re-use the watcher with a new future and cancel the previous future afterwards.

another question in this regards: the docs state that a QFuture is reference counted, but what does that mean to the lifetime of i.e. a QFuture object returned by QtConcurrent? does adding and removing a future to/from a watcher (the way i do it above) trigger reference counting, and would that mean that the future is destroyed when it is removed from the (last) watcher, even if it is still working? somehow i don't get a clear view on this by what the docs say...

wysota
11th February 2015, 08:17
thanks!

i forgot to add that i also decided to use a watcher because this seems to be the easiest way to also have throttling - so the original question remains.
The only thing a watcher adds to QFuture is the ability to emit signals, nothing else.


another question in this regards: the docs state that a QFuture is reference counted, but what does that mean to the lifetime of i.e. a QFuture object returned by QtConcurrent?

It means that if you copy the future and destroy the original, the copy retains the personality of the original. Thus if you set a future on a watcher (copy) and destroy the original one, the future still functions in the watcher. "Reference counting" is nothing unique to Qt, just STFW for this term.

t_3
12th February 2015, 00:59
The only thing a watcher adds to QFuture is the ability to emit signals, nothing else.
thanks again... but...

"The setPendingResultsLimit() provides throttling control. When the number of pending resultReadyAt() or resultsReadyAt() signals exceeds the limit, the computation represented by the future will be throttled automatically. The computation will resume once the number of pending signals drops below the limit."

as this method is only available through the watcher but not the future itself, the statement from the docs is either wrong or i did badly misinterpret it? i also read it in a way it doesn't matter if the (any) signals are connected at all?

wysota
12th February 2015, 09:42
If you do not connect any signals from the watcher tthen I don't see how throttling is of any use to you. It makes sense only if the producer is faster than the consumer for really large data sets where resource consumption matters. If you are not processing entries as they appear in the result (which would require the use of signals) then if throttling kicked in your operation would never complete.

Maybe you should describe what you are trying to achieve with QtConcurrent, why you need throttling and how you process the results.

t_3
12th February 2015, 12:20
If you do not connect any signals from the watcher tthen I don't see how throttling is of any use to you. It makes sense only if the producer is faster than the consumer for really large data sets where resource consumption matters. If you are not processing entries as they appear in the result (which would require the use of signals) then if throttling kicked in your operation would never complete.

Maybe you should describe what you are trying to achieve with QtConcurrent, why you need throttling and how you process the results.
i process [some of the] future results in the main/ui thread, but for particular reasons i'm using own signals instead of the watcher ones.

i work on a plugin that needs to access two different, both non thread safe api's (one from a Qt based host application, and external other one), so whenever i like to offload processing to keep the ui responsive it gets complicated, not the last because i have only very limited control - for example the threadpool threads limit; in this particular case the thread limit is already way beyond what is healthy for the particular modules task (thumbnails rendering on a gpu), so i need a way to limit concurrent processing on my own.

the key part in the docs description is the wording "pending signals". i of course see that to calculate a "pending" number (to test against a limit) needs something that adds and removes signals from a "pending" list (however that works). means you are probably right that watcher throttling won't work if i don't use the internal methods to consume results. after some test it seems that the setting has just no effect at all in this case - even if i set the limit to "1" the filter still runs down the sequence without being ever paused... so i'm going to use a semaphore.

thanks for your help...