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

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