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

source code of qtbase/src/concurrent/qtconcurrentrun.cpp