Concurrent map equivalent
-
Hi
I think concurrent will be more fun as it dont block the GUI thread.
as in.void mapFunction(int& n) { qDebug() << n; } void test() { QList<int>* vectorOfInts = new QList<int>; for (int i = 0; i < 1000; i++) vectorOfInts->push_back(i); QFuture<void> future = QtConcurrent::map(*vectorOfInts, mapFunction); } // end of scope
-
@Defohin said in Concurrent map equivalent:
What you mean with names surviving the scope?
He means this from the docs for
QtConcurrent::map
:Calls function once for each item in sequence. The function is passed a reference to the item, so that any modifications done to the item will appear in sequence.
Once you leave the scope of the function, the reference you'd passed is invalid and the program crashes. Perhaps you need
mapped()
instead?@kshegunov I tried using mapped but it doesn't work with lambdas.
I removed the
waitForFinished
and it's working... but I don't know if something bad will happen by doing that... -
Hi
I think concurrent will be more fun as it dont block the GUI thread.
as in.void mapFunction(int& n) { qDebug() << n; } void test() { QList<int>* vectorOfInts = new QList<int>; for (int i = 0; i < 1000; i++) vectorOfInts->push_back(i); QFuture<void> future = QtConcurrent::map(*vectorOfInts, mapFunction); } // end of scope
-
I just realized something... if though it's working, if I close the window it will continue running...
What can I do?
@Defohin
Hi , i think you can cancel via
http://doc.qt.io/qt-5/qfuture.html#cancel
http://doc.qt.io/qt-5/qfuturewatcher.html#cancelI think you need to use QFutureWatcher if u dont use waitForFinished.
All credits to @kshegunov :) -
@Defohin
Hi , i think you can cancel via
http://doc.qt.io/qt-5/qfuture.html#cancel
http://doc.qt.io/qt-5/qfuturewatcher.html#cancelI think you need to use QFutureWatcher if u dont use waitForFinished.
All credits to @kshegunov :) -
Be aware that not all asynchronous computations can be canceled. For example, the QFuture returned by QtConcurrent::run() cannot be canceled; but the QFuture returned by QtConcurrent::mappedReduced() can.
:(
-
I don't want the pause, continue or the stop function, I just want to run a list of string over a method and pass additional arguments to it in parallel.
UsingQtConcurrent::map
won't work cause I can't pass additional arguments.
UsingQtConcurrent::run
won't work cause I'll need to callwaitForFinished
and it will block the GUI thread... (QFutureWatcher::cancel
orQFuture::cancel
won't work either cause it's not possible to cancel aQFuture
returned byQtConcurrent::run
)...What can I do? I'm out of ideas.
-
I don't want the pause, continue or the stop function, I just want to run a list of string over a method and pass additional arguments to it in parallel.
UsingQtConcurrent::map
won't work cause I can't pass additional arguments.
UsingQtConcurrent::run
won't work cause I'll need to callwaitForFinished
and it will block the GUI thread... (QFutureWatcher::cancel
orQFuture::cancel
won't work either cause it's not possible to cancel aQFuture
returned byQtConcurrent::run
)...What can I do? I'm out of ideas.
like this:
QStringList names = { "john", "jane" }; // global or member variable void YourClass::startJobs() { QString extra = "doe"; auto example = [extra] (QString &name) { qDebug() << name << extra; }; QFuture<void> future = QtConcurrent::map(names, example); }
-
I don't want the pause, continue or the stop function, I just want to run a list of string over a method and pass additional arguments to it in parallel.
UsingQtConcurrent::map
won't work cause I can't pass additional arguments.
UsingQtConcurrent::run
won't work cause I'll need to callwaitForFinished
and it will block the GUI thread... (QFutureWatcher::cancel
orQFuture::cancel
won't work either cause it's not possible to cancel aQFuture
returned byQtConcurrent::run
)...What can I do? I'm out of ideas.
Hi
If cancel is a MUST have, then QThreads seems the only option :( -
like this:
QStringList names = { "john", "jane" }; // global or member variable void YourClass::startJobs() { QString extra = "doe"; auto example = [extra] (QString &name) { qDebug() << name << extra; }; QFuture<void> future = QtConcurrent::map(names, example); }
-
@Devopia53 It's still crashing for me.
@mrjj I don't want to usecancel
, as i said, I just want to run in parallel the method for each item of a string list and pass a few additional arguments. No need to cancel.@Defohin said in Concurrent map equivalent:
No need to cancel.
By cancel i mean to terminate before its finished. Like closing program.
In that regards you need "cancel" :) -
@Defohin said in Concurrent map equivalent:
No need to cancel.
By cancel i mean to terminate before its finished. Like closing program.
In that regards you need "cancel" :) -
I don't want the pause, continue or the stop function, I just want to run a list of string over a method and pass additional arguments to it in parallel.
UsingQtConcurrent::map
won't work cause I can't pass additional arguments.
UsingQtConcurrent::run
won't work cause I'll need to callwaitForFinished
and it will block the GUI thread... (QFutureWatcher::cancel
orQFuture::cancel
won't work either cause it's not possible to cancel aQFuture
returned byQtConcurrent::run
)...What can I do? I'm out of ideas.
@Defohin said in Concurrent map equivalent:
Using QtConcurrent::map won't work cause I can't pass additional arguments.
Just use a function object
struct MapHelper{ MapHelper(){} QString m_additionalArgument1; QString m_additionalArgument2; typedef QString result_type; QString operator()(const QString &val) { return m_additionalArgument1+val+additionalArgument2; } } MapHelper helper; // TODO: make sure to manage its lifecycle helper.m_additionalArgument1 = "Prefix "; helper.m_additionalArgument2 = " Suffix"; QtConcurrent::map(list_of_names,helper);
-
@VRonin How to get the return from each one now?
struct NameHelper { NameHelper(const QString &extra) : _extra(extra) { } typedef QString result_type; QString operator()(const QString &name) { return QString("Hello %1 %2").arg(name).arg(_extra); } QString _extra; }; QStringList names = { "john", "jane" }; QString extra = "doe"; QFuture<QString> example = QtConcurrent::mapped(names, NameHelper(extra));
example.result()
is returning only"Hello john doe"
. -
You can achieve the same with C++11 std::bind:
QString concatenate(const QString& prefix,const QString& val,const QString& suffix){return prefix+val+suffix;} QtConcurrent::mapped(list_of_names,std::bind(concatenate,"Prefix ",std::placeholders::_1," Suffix"));
How to get the return from each one now?
[...]
example.result() is returning only "Hello john doe".use
results()
instead ofresult()
-
It's working nicely, but one last question; Is it GUI blocking? I tried to use a for loop inside of the function and it's now showing anything until it's finished.
-
struct NameHelper { NameHelper(const QString &extra) : _extra(extra) { } typedef QString result_type; QString operator()(const QString &name) { for(int i = 0; i < 999999; ++i) { qDebug() << "block"; } return QString("Hello %1 %2").arg(name).arg(_extra); } QString _extra; }; QStringList names = { "john", "jane" }; QString extra = "doe"; QFuture<QString> example = QtConcurrent::mapped(names, NameHelper(extra));