[Interest] [External]Re: How to get QtConcurrent to do what I want?
Murphy, Sean
Sean.Murphy at centauricorp.com
Tue Feb 1 19:35:59 CET 2022
> Depending on your QFuture setup, you could monitor each tile, and when it
> completes, update the min max...
I think from the testing I did yesterday, and this comment from
https://doc.qt.io/qt-5/qfuturewatcher.html prevents you from knowing WHICH
result is ready if your map function returns void:
"QFutureWatcher<void> is specialized to not contain any of the result fetching
functions. Any QFuture<T> can be watched by a QFutureWatcher<void> as well.
This is useful if only status or progress information is needed; not the actual
result data."
One of my early go arounds yesterday had me connecting the
QFutureWatcher<void>::resultReadyAt(int index) from the watcher that was monitoring
the tile::load() call to a slot in my tileManager class. That slot was never called. If I
used the QFutureWatcher<void>::progressValueChanged(int progressValue) signal
instead, the slot was called as each tile completed. But the issue there is that you
only know HOW MANY have completed, not WHICH ONES.
So from what I could tell, if you want to work with the result of an individual item right
when it comes in, the function you pass as the map function has to have a non-void return
type so that you aren't instantiating a QFutureWatcher<void> which doesn't fire those signals,
but instead instantiate a QFutureWatcher<T> and then you can use the resultReadyAt(int index)
> Passing the manager to each tile, and when the tile is finished update the
> manager with the tiles value. Then a simple mutex should allow you to not
> collide. No signals, just a simple function call.
Oh man, my head is already bursting with the QtConcurrent and QFuture stuff, now you want to
toss QMutex at me too?!?! 😉
> When the future watcher says all tiles are done, you will also have the
> min/max computed at that point, so you can kick off phase 2.
>
> While I love the signal slot for "generic, I don’t know who needs this
> information" type design. Sometimes the cost/overhead of being a qobject
> and sending the signal, especially when it’s a very discrete "signal" and not
> generic in any means, it can be overkill.
>
> To me, the manager you have doesn’t need to know "is a tile finished", ie a
> generic signal. But rather what Is the min max of the tile when finished a
> specific signal. For that level, a simple function works.
From where I'm at right now, I think that can be accomplished by changing my
loadTile function from:
void loadTile(tile &t)
{
t.load();
}
QPair<double,double> loadTile(tile &t)
{
t.load();
return t.getMinMax();
}
Then change to QtConcurrent::mapped() instead of map() since my future type
is now QPair<double, double> and then I can connect the
QFutureWatcher<QPair<double, double>>::resultReadyAt(int index) to a slot that
updates the global min/max.
Although as I'm reading through everything, this also might the point to use
QtConcurrent::mappedReduced(). So many options to choose from...
Sean
More information about the Interest
mailing list