QtConcurrent: Add documentation for runWithPromise()
Task-number: QTBUG-84702 Change-Id: Ic8233aeffbdbd1420bdbde7ad7d03f25cd438ea8 Reviewed-by: Paul Wicking <paul.wicking@qt.io>
This commit is contained in:
parent
77e04acb4e
commit
cba2d04434
@ -144,3 +144,89 @@ QtConcurrent::run(TestClass(), 42).waitForFinished();
|
||||
// Ill-formed
|
||||
QtConcurrent::run(&o, 42).waitForFinished(); // compilation error
|
||||
//! [8]
|
||||
|
||||
//! [9]
|
||||
extern void aFunction(QPromise<void> &promise);
|
||||
QFuture<void> future = QtConcurrent::runWithPromise(aFunction);
|
||||
//! [9]
|
||||
|
||||
//! [10]
|
||||
extern void aFunction(QPromise<void> &promise, int arg1, const QString &arg2);
|
||||
|
||||
int integer = ...;
|
||||
QString string = ...;
|
||||
|
||||
QFuture<void> future = QtConcurrent::runWithPromise(aFunction, integer, string);
|
||||
//! [10]
|
||||
|
||||
//! [11]
|
||||
void helloWorldFunction(QPromise<QString> &promise)
|
||||
{
|
||||
promise.addResult("Hello");
|
||||
promise.addResult("world");
|
||||
}
|
||||
|
||||
QFuture<QString> future = QtConcurrent::runWithPromise(helloWorldFunction);
|
||||
...
|
||||
QList<QString> results = future.results();
|
||||
//! [11]
|
||||
|
||||
//! [12]
|
||||
void aFunction(QPromise<int> &promise)
|
||||
{
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
promise.suspendIfRequested();
|
||||
if (promise.isCanceled())
|
||||
return;
|
||||
|
||||
// computes the next result, may be time consuming like 1 second
|
||||
const int res = ... ;
|
||||
promise.addResult(res);
|
||||
}
|
||||
}
|
||||
|
||||
QFuture<int> future = QtConcurrent::runWithPromise(aFunction);
|
||||
|
||||
... // user pressed a pause button after 10 seconds
|
||||
future.suspend();
|
||||
|
||||
... // user pressed a resume button after 10 seconds
|
||||
future.resume();
|
||||
|
||||
... // user pressed a cancel button after 10 seconds
|
||||
future.cancel();
|
||||
//! [12]
|
||||
|
||||
//! [13]
|
||||
void aFunction(QPromise<int> &promise)
|
||||
{
|
||||
promise.setProgressRange(0, 100);
|
||||
int result = 0;
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
// computes some part of the task
|
||||
const int part = ... ;
|
||||
result += part;
|
||||
promise.setProgressValue(i);
|
||||
}
|
||||
promise.addResult(result);
|
||||
}
|
||||
|
||||
QFutureWatcher<int> watcher;
|
||||
QObject::connect(&watcher, &QFutureWatcher::progressValueChanged, [](int progress){
|
||||
... ; // update GUI with a progress
|
||||
qDebug() << "current progress:" << progress;
|
||||
});
|
||||
watcher.setFuture(QtConcurrent::runWithPromise(aFunction));
|
||||
//! [13]
|
||||
|
||||
//! [14]
|
||||
struct Functor {
|
||||
void operator()(QPromise<int> &) { }
|
||||
void operator()(QPromise<double> &) { }
|
||||
};
|
||||
|
||||
Functor f;
|
||||
runWithPromise<double>(f); // this will select the 2nd overload
|
||||
// runWithPromise(f); // error, both candidate overloads potentially match
|
||||
//! [14]
|
||||
|
||||
|
@ -81,10 +81,15 @@
|
||||
folded into a single result.
|
||||
\endlist
|
||||
|
||||
\li \l {Concurrent Run}
|
||||
\li \l {Concurrent Run and Run With Promise}
|
||||
\list
|
||||
\li \l {QtConcurrent::run}{QtConcurrent::run()} runs a function in
|
||||
another thread.
|
||||
\li \l {QtConcurrent::runWithPromise}{QtConcurrent::runWithPromise()}
|
||||
is like run(), except that the function to run accepts additional
|
||||
argument of QPromise type that enables more control over the function
|
||||
execution, like suspending or canceling the execution when requested,
|
||||
progress reporting or reporting multiple results.
|
||||
\endlist
|
||||
|
||||
\li \l {Concurrent Task}
|
||||
|
@ -49,7 +49,7 @@
|
||||
containing the filtered content, and QtConcurrent::filteredReduced()
|
||||
returns a single result.
|
||||
|
||||
These functions are a part of the \l {Qt Concurrent} framework.
|
||||
These functions are part of the \l {Qt Concurrent} framework.
|
||||
|
||||
Each of the above functions have a blocking variant that returns the final
|
||||
result instead of a QFuture. You use them in the same way as the
|
||||
|
@ -153,7 +153,7 @@
|
||||
sequence containing the modified content, and QtConcurrent::mappedReduced()
|
||||
returns a single result.
|
||||
|
||||
These functions are a part of the \l {Qt Concurrent} framework.
|
||||
These functions are part of the \l {Qt Concurrent} framework.
|
||||
|
||||
Each of the above functions has a blocking variant that returns
|
||||
the final result instead of a QFuture. You use them in the same
|
||||
|
@ -39,15 +39,27 @@
|
||||
|
||||
/*!
|
||||
\page qtconcurrentrun.html
|
||||
\title Concurrent Run
|
||||
\title Concurrent Run and Run With Promise
|
||||
\ingroup thread
|
||||
|
||||
The QtConcurrent::run() function runs a function in a separate thread.
|
||||
The QtConcurrent::run() and QtConcurrent::runWithPromise()
|
||||
functions run a function in a separate thread.
|
||||
The return value of the function is made available through the QFuture API.
|
||||
The function passed to QtConcurrent::run() is able to report merely
|
||||
a single computation result to its caller, while the function passed to
|
||||
QtConcurrent::runWithPromise() can make use of the additional
|
||||
QPromise API, which enables multiple result reporting, progress reporting,
|
||||
suspending the computation when requested by the caller, or stopping
|
||||
the computation on the caller's demand.
|
||||
|
||||
This function is a part of the \l {Qt Concurrent} framework.
|
||||
These functions are part of the Qt Concurrent framework.
|
||||
|
||||
\section1 Running a Function in a Separate Thread
|
||||
\section1 Concurrent Run
|
||||
|
||||
The function passed to QtConcurrent::run() may report the result
|
||||
through its return value.
|
||||
|
||||
\section2 Running a Function in a Separate Thread
|
||||
|
||||
To run a function in another thread, use QtConcurrent::run():
|
||||
|
||||
@ -62,7 +74,7 @@
|
||||
|
||||
\snippet code/src_concurrent_qtconcurrentrun.cpp explicit-pool-0
|
||||
|
||||
\section1 Passing Arguments to the Function
|
||||
\section2 Passing Arguments to the Function
|
||||
|
||||
Passing arguments to the function is done by adding them to the
|
||||
QtConcurrent::run() call immediately after the function name. For example:
|
||||
@ -74,7 +86,7 @@
|
||||
the function. Changes made to the arguments after calling
|
||||
QtConcurrent::run() are \e not visible to the thread.
|
||||
|
||||
\section1 Returning Values from the Function
|
||||
\section2 Returning Values from the Function
|
||||
|
||||
Any return value from the function is available via QFuture:
|
||||
|
||||
@ -88,9 +100,9 @@
|
||||
to become available. Use QFutureWatcher to get notification when the
|
||||
function has finished execution and the result is available.
|
||||
|
||||
\section1 Additional API Features
|
||||
\section2 Additional API Features
|
||||
|
||||
\section2 Using Member Functions
|
||||
\section3 Using Member Functions
|
||||
|
||||
QtConcurrent::run() also accepts pointers to member functions. The first
|
||||
argument must be either a const reference or a pointer to an instance of
|
||||
@ -107,7 +119,7 @@
|
||||
|
||||
\snippet code/src_concurrent_qtconcurrentrun.cpp 5
|
||||
|
||||
\section2 Using Lambda Functions
|
||||
\section3 Using Lambda Functions
|
||||
|
||||
Calling a lambda function is done like this:
|
||||
|
||||
@ -120,6 +132,86 @@
|
||||
Using callable object is done like this:
|
||||
|
||||
\snippet code/src_concurrent_qtconcurrentrun.cpp 8
|
||||
|
||||
\section1 Concurrent Run With Promise
|
||||
|
||||
The QtConcurrent::runWithPromise() enables more control
|
||||
for the running task comparing to QtConcurrent::run().
|
||||
It allows progress reporting of the running task,
|
||||
reporting multiple results, suspending the execution
|
||||
if it was requested, or canceling the task on caller's
|
||||
demand.
|
||||
|
||||
\section2 The mandatory QPromise argument
|
||||
|
||||
The function passed to QtConcurrent::runWithPromise() is expected
|
||||
to have an additional argument of \e {QPromise<T> &} type, where
|
||||
T is the type of the computation result (it should match the type T
|
||||
of QFuture<T> returned by the QtConcurrent::runWithPromise()), like e.g.:
|
||||
|
||||
\snippet code/src_concurrent_qtconcurrentrun.cpp 9
|
||||
|
||||
The \e promise argument is instantiated inside the
|
||||
QtConcurrent::runWithPromise() function, and its reference
|
||||
is passed to the invoked \e aFunction, so the user
|
||||
doesn't need to instantiate it by himself, nor pass it explicitly
|
||||
when calling QtConcurrent::runWithPromise().
|
||||
|
||||
The additional argument of QPromise type always needs to appear
|
||||
as a first argument on function's arguments list, like:
|
||||
|
||||
\snippet code/src_concurrent_qtconcurrentrun.cpp 10
|
||||
|
||||
\section2 Reporting results
|
||||
|
||||
In contrast to QtConcurrent::run(), the function passed to
|
||||
QtConcurrent::runWithPromise() is expected to always return void type.
|
||||
Result reporting is done through the additional argument of QPromise type.
|
||||
It also enables multiple result reporting, like:
|
||||
|
||||
\snippet code/src_concurrent_qtconcurrentrun.cpp 11
|
||||
|
||||
\section2 Suspending and canceling the execution
|
||||
|
||||
The QPromise API also enables suspending and canceling the computation, if requested:
|
||||
|
||||
\snippet code/src_concurrent_qtconcurrentrun.cpp 12
|
||||
|
||||
The call to \e future.suspend() requests the running task to
|
||||
hold its execution. After calling this method, the running task
|
||||
will suspend after the next call to \e promise.suspendIfRequested()
|
||||
in its iteration loop. In this case the running task will
|
||||
block on a call to \e promise.suspendIfRequested(). The blocked
|
||||
call will unblock after the \e future.resume() is called.
|
||||
Note, that internally suspendIfRequested() uses wait condition
|
||||
in order to unblock, so the running thread goes into an idle state
|
||||
instead of wasting its resources when blocked in order to periodically
|
||||
check if the resume request came from the caller's thread.
|
||||
|
||||
The call to \e future.cancel() from the last line causes that the next
|
||||
call to \e promise.isCanceled() will return \c true and
|
||||
\e aFunction will return immediately without any further result reporting.
|
||||
|
||||
\section2 Progress reporting
|
||||
|
||||
It's also possible to report the progress of a task
|
||||
independently of result reporting, like:
|
||||
|
||||
\snippet code/src_concurrent_qtconcurrentrun.cpp 13
|
||||
|
||||
The caller installs the \e QFutureWatcher for the \e QFuture
|
||||
returned by QtConcurrent::runWithPromise() in order to
|
||||
connect to its \e progressValueChanged() signal and update
|
||||
e.g. the graphical user interface accordingly.
|
||||
|
||||
\section2 Invoking functions with overloaded operator()()
|
||||
|
||||
By default, QtConcurrent::runWithPromise() doesn't support functors with
|
||||
overloaded operator()(). In case of overloaded functors the user
|
||||
needs to explicitly specify the result type
|
||||
as a template parameter passed to runWithPromise, like:
|
||||
|
||||
\snippet code/src_concurrent_qtconcurrentrun.cpp 14
|
||||
*/
|
||||
|
||||
/*!
|
||||
@ -172,3 +264,52 @@
|
||||
|
||||
\sa {Concurrent Run}
|
||||
*/
|
||||
|
||||
/*!
|
||||
\since 6.0
|
||||
\fn QFuture<T> QtConcurrent::runWithPromise(Function function, ...);
|
||||
|
||||
Equivalent to
|
||||
\code
|
||||
QtConcurrent::runWithPromise(QThreadPool::globalInstance(), function, ...);
|
||||
\endcode
|
||||
|
||||
Runs \a function in a separate thread. The thread is taken from the global
|
||||
QThreadPool. Note that \a function may not run immediately; \a function
|
||||
will only be run once a thread becomes available.
|
||||
|
||||
The \a function is expected to return void
|
||||
and must take an additional argument of \e {QPromise<T> &} type,
|
||||
placed as a first argument in function's argument list. T is the result type
|
||||
and it is the same for the returned \e QFuture<T>.
|
||||
|
||||
Similar to QtConcurrent::run(), the QFuture returned can be used to query for the
|
||||
running/finished status and the value reported by the function. In addition,
|
||||
it may be used for suspending or canceling the running task, fetching
|
||||
multiple results from the called /a function or monitoring progress
|
||||
reported by the \a function.
|
||||
|
||||
\sa {Concurrent Run With Promise}
|
||||
*/
|
||||
|
||||
/*!
|
||||
\since 6.0
|
||||
\fn QFuture<T> QtConcurrent::runWithPromise(QThreadPool *pool, Function function, ...);
|
||||
|
||||
Runs \a function in a separate thread. The thread is taken from the
|
||||
QThreadPool \a pool. Note that \a function may not run immediately; \a function
|
||||
will only be run once a thread becomes available.
|
||||
|
||||
The \a function is expected to return void
|
||||
and must take an additional argument of \e {QPromise<T> &} type,
|
||||
placed as a first argument in function's argument list. T is the result type
|
||||
and it is the same for the returned \e QFuture<T>.
|
||||
|
||||
Similar to QtConcurrent::run(), the QFuture returned can be used to query for the
|
||||
running/finished status and the value reported by the function. In addition,
|
||||
it may be used for suspending or canceling the running task, fetching
|
||||
multiple results from the called /a function or monitoring progress
|
||||
reported by the \a function.
|
||||
|
||||
\sa {Concurrent Run With Promise}
|
||||
*/
|
||||
|
@ -61,6 +61,12 @@ namespace QtConcurrent {
|
||||
template <typename T>
|
||||
QFuture<T> run(QThreadPool *pool, Function function, ...);
|
||||
|
||||
template <typename T>
|
||||
QFuture<T> runWithPromise(Function function, ...);
|
||||
|
||||
template <typename T>
|
||||
QFuture<T> runWithPromise(QThreadPool *pool, Function function, ...);
|
||||
|
||||
} // namespace QtConcurrent
|
||||
|
||||
#else
|
||||
|
Loading…
x
Reference in New Issue
Block a user