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*/