Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qtconcurrentrun.cpp
Go to the documentation of this file.
1
// Copyright (C) 2016 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
// Qt-Security score:significant reason:default
4
5
/*!
6
\page qtconcurrentrun.html
7
\title Concurrent Run
8
\brief A simple way to run a task in a separate thread.
9
\ingroup thread
10
11
The QtConcurrent::run() function runs a function in a separate thread.
12
The return value of the function is made available through the QFuture API.
13
14
QtConcurrent::run() is an overloaded method. You can think of these overloads as slightly
15
different \e modes.
16
In \l {Concurrent Run (basic mode)} {basic mode}, the function passed to QtConcurrent::run()
17
is able to report merely a single computation result to its caller.
18
In \l {Concurrent Run With Promise} {run with promise mode}, the function passed to
19
QtConcurrent::run() can make use of the additional
20
QPromise API, which enables multiple result reporting, progress reporting,
21
suspending the computation when requested by the caller, or stopping
22
the computation on the caller's demand.
23
24
This function is a part of the Qt Concurrent framework.
25
26
\section1 Optimize includes
27
28
If you include the \c <QtConcurrent> header, the entire Qt Concurrent
29
module with the entire Qt Core module will be included, which may increase
30
compilation times and binary sizes. To use the
31
\l {QtConcurrent::run}{QtConcurrent::run()} function, you can include a
32
more specific header:
33
34
\code
35
#include <QtConcurrentRun>
36
\endcode
37
38
\section1 Concurrent Run (basic mode)
39
40
The function passed to QtConcurrent::run() may report the result
41
through its return value.
42
43
\section2 Running a Function in a Separate Thread
44
45
To run a function in another thread, use QtConcurrent::run():
46
47
\snippet code/src_concurrent_qtconcurrentrun.cpp 0
48
49
This will run \c aFunction in a separate thread obtained from the default
50
QThreadPool. You can use the QFuture and QFutureWatcher classes to monitor
51
the status of the function.
52
53
To use a dedicated thread pool, you can pass the QThreadPool as
54
the first argument:
55
56
\snippet code/src_concurrent_qtconcurrentrun.cpp explicit-pool-0
57
58
\section2 Passing Arguments to the Function
59
60
Passing arguments to the function is done by adding them to the
61
QtConcurrent::run() call immediately after the function name. For example:
62
63
\snippet code/src_concurrent_qtconcurrentrun.cpp 1
64
65
A copy of each argument is made at the point where QtConcurrent::run() is
66
called, and these values are passed to the thread when it begins executing
67
the function. Changes made to the arguments after calling
68
QtConcurrent::run() are \e not visible to the thread.
69
70
Note that QtConcurrent::run does not support calling overloaded functions
71
directly. For example, the code below won't compile:
72
73
//! [run-with-overload-calls]
74
\snippet code/src_concurrent_qtconcurrentrun.cpp 15
75
76
The easiest workaround is to call the overloaded function through lambda:
77
78
\snippet code/src_concurrent_qtconcurrentrun.cpp 16
79
80
Or you can tell the compiler which overload to choose by using a
81
\c static_cast:
82
83
\snippet code/src_concurrent_qtconcurrentrun.cpp 17
84
85
Or qOverload:
86
87
\snippet code/src_concurrent_qtconcurrentrun.cpp 18
88
//! [run-with-overload-calls]
89
90
\section2 Returning Values from the Function
91
92
Any return value from the function is available via QFuture:
93
94
\snippet code/src_concurrent_qtconcurrentrun.cpp 2
95
96
If you don't need the result (for example, because the function returns
97
\c{void}), using the QThreadPool::start() overload taking a function object
98
is more efficient.
99
100
As documented above, passing arguments is done like this:
101
102
\snippet code/src_concurrent_qtconcurrentrun.cpp 3
103
104
Note that the QFuture::result() function blocks and waits for the result
105
to become available. Use QFutureWatcher to get notification when the
106
function has finished execution and the result is available.
107
108
\section2 Additional API Features
109
110
\section3 Using Member Functions
111
112
QtConcurrent::run() also accepts pointers to member functions.
113
In Qt 6, the first argument must be the pointer to the member function,
114
followed by either a const reference or a pointer to an instance of the
115
class. Passing a const reference is useful when calling const member
116
functions; passing a pointer is useful for calling non-const member
117
functions that modify the instance.
118
119
For example, calling QByteArray::split() (a const member function) in a
120
separate thread is done like this:
121
122
\snippet code/src_concurrent_qtconcurrentrun.cpp 4
123
124
Calling a non-const member function is done like this:
125
126
\snippet code/src_concurrent_qtconcurrentrun.cpp 5
127
128
\section3 Using Lambda Functions
129
130
Calling a lambda function is done like this:
131
132
\snippet code/src_concurrent_qtconcurrentrun.cpp 6
133
134
Calling a function modifies an object passed by reference is done like this:
135
136
\snippet code/src_concurrent_qtconcurrentrun.cpp 7
137
138
Using callable object is done like this:
139
140
\snippet code/src_concurrent_qtconcurrentrun.cpp 8
141
142
\section1 Concurrent Run With Promise
143
144
The \e {Run With Promise} mode enables more control for the running
145
task compared to \e basic mode of QtConcurrent::run().
146
It allows progress reporting of the running task,
147
reporting multiple results, suspending the execution
148
if it was requested, or canceling the task on caller's
149
demand.
150
151
\section2 The mandatory QPromise argument
152
153
The function passed to QtConcurrent::run() in \e {Run With Promise} mode
154
is expected to have an additional argument of \c {QPromise<T> &} type, where
155
\c T is the type of the computation result (it should match the type \c T
156
of QFuture<T> returned by QtConcurrent::run()), like e.g.:
157
158
\snippet code/src_concurrent_qtconcurrentrun.cpp 9
159
160
The \c promise argument is instantiated inside the QtConcurrent::run()
161
function, and its reference is passed to the invoked \c aFunction, so the
162
user doesn't need to instantiate it, nor pass it explicitly
163
when calling QtConcurrent::run() in this mode.
164
165
The additional argument of QPromise type always needs to appear
166
as a first argument on function's arguments list, like:
167
168
\snippet code/src_concurrent_qtconcurrentrun.cpp 10
169
170
\section2 Reporting results
171
172
In contrast to \e basic mode of QtConcurrent::run(), the function passed to
173
QtConcurrent::run() in \e {Run With Promise} mode is expected to always return void type.
174
Result reporting is done through the additional argument of QPromise type.
175
It also enables multiple result reporting, like:
176
177
\snippet code/src_concurrent_qtconcurrentrun.cpp 11
178
179
\note There's no need to call QPromise::start() and QPromise::finish() to
180
indicate the beginning and the end of computation (like you would normally do when
181
using QPromise). QtConcurrent::run() will always call them before starting and
182
after finishing the execution.
183
184
\section2 Suspending and canceling the execution
185
186
The QPromise API also enables suspending and canceling the computation, if requested:
187
188
\snippet code/src_concurrent_qtconcurrentrun.cpp 12
189
190
The call to \c future.suspend() requests the running task to
191
hold its execution. After calling this method, the running task
192
will suspend after the next call to \c promise.suspendIfRequested()
193
in its iteration loop. In this case the running task will
194
block on a call to \c promise.suspendIfRequested(). The blocked
195
call will unblock after the \c future.resume() is called.
196
Note, that internally suspendIfRequested() uses wait condition
197
in order to unblock, so the running thread goes into an idle state
198
instead of wasting its resources when blocked in order to periodically
199
check if the resume request came from the caller's thread.
200
201
The call to \c future.cancel() from the last line causes that the next
202
call to \c promise.isCanceled() will return \c true and
203
\c aFunction will return immediately without any further result reporting.
204
205
\note There's no need to call QPromise::finish() to stop the computation
206
after the cancellation (like you would normally do when using QPromise).
207
QtConcurrent::run() will always call it after finishing the execution.
208
209
\section2 Progress reporting
210
211
It's also possible to report the progress of a task
212
independently of result reporting, like:
213
214
\snippet code/src_concurrent_qtconcurrentrun.cpp 13
215
216
The caller installs the \c QFutureWatcher for the \c QFuture
217
returned by QtConcurrent::run() in order to
218
connect to its \c progressValueChanged() signal and update
219
e.g. the graphical user interface accordingly.
220
221
\section2 Invoking functions with overloaded operator()()
222
223
By default, QtConcurrent::run() doesn't support functors with
224
overloaded operator()() in \e {Run With Promise} mode. In case of overloaded
225
functors the user needs to explicitly specify the result type
226
as a template parameter passed to QtConcurrent::run(), like:
227
228
\snippet code/src_concurrent_qtconcurrentrun.cpp 14
229
*/
230
231
/*!
232
\typedef Function
233
\internal
234
235
This typedef is a dummy required to make the \c Function
236
type name known so that clang doesn't reject functions
237
that use it.
238
*/
239
240
/*!
241
\fn template <typename T> QFuture<T> QtConcurrent::run(Function function, ...);
242
243
Equivalent to
244
\code
245
QtConcurrent::run(QThreadPool::globalInstance(), function, ...);
246
\endcode
247
248
Runs \a function in a separate thread. The thread is taken from the global
249
QThreadPool. Note that \a function may not run immediately; \a function
250
will only be run once a thread becomes available.
251
252
//! [run-description]
253
In \l {Concurrent Run (basic mode)} {basic mode} T is the same type as the return value
254
of \a function. Non-void return values can be accessed via the QFuture::result() function.
255
256
In \l {Concurrent Run (basic mode)} {basic mode} the QFuture returned can only be used to
257
query for the running/finished status and the return value of the function. In particular,
258
canceling or pausing can be issued only if the computations behind the future
259
has not been started.
260
261
In \l {Concurrent Run With Promise} {run with promise mode}, the \a function is expected
262
to return void and must take an additional argument of \c {QPromise<T> &} type,
263
placed as a first argument in function's argument list. T is the result type
264
and it is the same for the returned \c QFuture<T>.
265
266
In \l {Concurrent Run With Promise} {run with promise mode}, similar to \e basic mode, the
267
QFuture returned can be used to query for the running/finished status and the value reported
268
by the function. In addition, it may be used for suspending or canceling the
269
running task, fetching multiple results from the called \a function or
270
monitoring progress reported by the \a function.
271
272
\sa {Concurrent Run (basic mode)}, {Concurrent Run With Promise}, QThreadPool::start()
273
//! [run-description]
274
*/
275
276
/*!
277
\since 5.4
278
\fn template <typename T> QFuture<T> QtConcurrent::run(QThreadPool *pool, Function function, ...);
279
280
Schedules \a function on \a pool. Note that \a function may not run
281
immediately; \a function will only be run once a thread becomes available.
282
283
\include qtconcurrentrun.cpp run-description
284
*/
qtbase
src
concurrent
qtconcurrentrun.cpp
Generated on
for Qt by
1.14.0