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
qpromise.qdoc
Go to the documentation of this file.
1
// Copyright (C) 2020 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
3
4
/*! \class QPromise
5
\inmodule QtCore
6
\threadsafe
7
\brief The QPromise class provides a way to store computation results to be accessed by QFuture.
8
\since 6.0
9
10
\ingroup thread
11
12
QPromise is a template class where the template parameter \a T specifies
13
the result type that can be stored and later accessed via QFuture.
14
15
QPromise provides a simple way to communicate progress and results of the
16
user-defined computation to QFuture in an asynchronous fashion. For the
17
communication to work, QFuture must be constructed by QPromise.
18
19
You can use QPromise based workloads as an alternative to \l {Qt Concurrent}
20
framework when fine-grained control is needed or high-level communication
21
primitive to accompany QFuture is sufficient.
22
23
The simplest case of promise and future collaboration would be a single
24
result communication:
25
26
\snippet snippet_qpromise.cpp basic
27
28
By design, QPromise is a move-only object. This behavior helps to ensure
29
that whenever the promise is destroyed, the associated future object is
30
notified and will not wait forever for the results to become available.
31
However, this is inconvenient if one wants to use the same promise to report
32
results from different threads. There is no specific way to do that at the
33
moment, but known mechanisms exist, such as the use of smart pointers or raw
34
pointers/references. QSharedPointer is a good default choice if you want to
35
copy your promise and use it in multiple places simultaneously. Raw pointers
36
or references are, in a sense, easier, and probably perform better (since
37
there is no need to do a resource management) but may lead to dangling.
38
39
Here is an example of how a promise can be used in multiple threads:
40
41
\snippet snippet_qpromise.cpp multithread_init
42
\codeline
43
\snippet snippet_qpromise.cpp multithread_main
44
\codeline
45
\snippet snippet_qpromise.cpp multithread_cleanup
46
47
\sa QFuture
48
*/
49
50
/*! \fn template <typename T> QPromise<T>::QPromise()
51
52
Constructs a QPromise with a default state.
53
*/
54
55
/*! \fn template <typename T> QPromise<T>::QPromise(QPromise<T> &&other)
56
57
Move constructs a new QPromise from \a other.
58
59
\sa operator=()
60
*/
61
62
/*! \fn template <typename T> QPromise<T>::QPromise(const QFutureInterface<T> &other)
63
\fn template <typename T> QPromise<T>::QPromise(QFutureInterface<T> &&other) noexcept
64
65
\internal
66
Constructs a QPromise with a passed QFutureInterface \a other.
67
Used internally for QtConcurrent::run(), when its callable takes
68
a reference to the associated promise as its first argument
69
(run with promise mode).
70
71
\sa operator=()
72
*/
73
74
75
/*! \fn template <typename T> QPromise<T> &QPromise<T>::operator=(QPromise<T> &&other)
76
77
Move assigns \a other to this promise and returns a reference to this
78
promise.
79
*/
80
81
/*! \fn template <typename T> QPromise<T>::~QPromise()
82
83
Destroys the promise.
84
85
\note The promise implicitly transitions to a canceled state on destruction
86
unless finish() is called beforehand by the user.
87
*/
88
89
/*! \fn template <typename T> QFuture<T> QPromise<T>::future() const
90
91
Returns a future associated with this promise.
92
*/
93
94
/*! \fn template <typename T> bool QPromise<T>::addResult(const T &result, int index = -1)
95
\fn template <typename T> bool QPromise<T>::addResult(T &&result, int index = -1)
96
97
Same as
98
\code
99
emplaceResultAt(index, result); // first overload
100
emplaceResultAt(index, std::move(result)); // second overload
101
\endcode
102
or, if \c{index == -1} (the default)
103
\code
104
emplaceResult(result); // first overload
105
emplaceResult(std::move(result)); // second overload
106
\endcode
107
108
\sa emplaceResultAt(), emplaceResult(), addResults()
109
*/
110
111
/*!
112
\fn template <typename T> template <typename...Args, std::enable_if_t<std::is_constructible_v<T, Args...>, bool> = true> bool QPromise<T>::emplaceResultAt(int index, Args&&...args)
113
\fn template <typename T> template <typename...Args, std::enable_if_t<std::is_constructible_v<T, Args...>, bool> = true> bool QPromise<T>::emplaceResult(Args&&...args)
114
\since 6.6
115
116
Adds a result constructed from \a args... to the internal result collection
117
at \a index position (emplaceResultAt()) or the end of of the collection
118
(emplaceResult()).
119
120
Returns \c true when the result was added to the collection.
121
122
Returns \c false when this promise is in canceled or finished state or when
123
the result was rejected. addResult() rejects to add a result if there's already
124
another result in the collection stored at the same index.
125
126
These functions only participate in overload resolutions if \c T is
127
constructible from \a args....
128
129
You can get a result at a specific index by calling QFuture::resultAt().
130
131
\note It is possible to specify an arbitrary index and request result at
132
that index. However, some QFuture methods operate with continuous results.
133
For instance, iterative approaches that use QFuture::resultCount() or
134
QFuture::const_iterator. In order to get all available results without
135
thinking if there are index gaps or not, use QFuture::results().
136
137
\sa addResult(), addResults()
138
*/
139
140
/*!
141
\fn template <typename T> bool QPromise<T>::addResults(const QList<T> &results)
142
\since 6.6
143
144
Adds \a results at the end of the internal result collection.
145
146
Returns \c true when \a results are added to the collection.
147
148
Returns \c false when this promise is in canceled or finished state.
149
150
This is more efficient than looping over addResult(), because associated
151
futures will be notified only once per addResults() call, instead of once
152
per element contained in \a results, as would be the case with individual
153
addResult() calls. But if the calculation of each element takes time, then
154
the code on the receiving end (future) cannot make progress until all
155
results are reported, so use this function only if the calculation of
156
consecutive elements is relatively fast.
157
158
\sa addResult()
159
*/
160
161
/*! \fn template<typename T> void QPromise<T>::setException(const QException &e)
162
163
Sets exception \a e to be the result of the computation.
164
165
\note You can set at most one exception throughout the computation
166
execution.
167
168
\note This method has no effect after QFuture::cancel() or
169
finish().
170
171
\sa isCanceled()
172
*/
173
174
#
if
QT_VERSION
<
QT_VERSION_CHECK
(
7
,
0
,
0
)
175
/*! \fn template<typename T> void QPromise<T>::setException(std::exception_ptr e)
176
177
\overload
178
*/
179
#
else
180
/*! \fn template<typename T> void QPromise<T>::setException(const std::exception_ptr &e)
181
182
\overload
183
*/
184
#
endif
185
186
/*! \fn template<typename T> void QPromise<T>::start()
187
188
Reports that the computation is started. Calling this method is important to
189
state the beginning of the computation as QFuture methods rely on this
190
information.
191
192
\note Extra attention is required when start() is called from a
193
newly created thread. In such case, the call might naturally be delayed due
194
to the implementation details of the thread scheduling.
195
196
\sa QFuture::isStarted(), QFuture::waitForFinished(), finish()
197
*/
198
199
/*! \fn template<typename T> void QPromise<T>::finish()
200
201
Reports that the computation is finished. Once finished, no new results will
202
be added when calling addResult(). This method accompanies start().
203
204
\sa QFuture::isFinished(), QFuture::waitForFinished(), start()
205
*/
206
207
/*! \fn template<typename T> void QPromise<T>::suspendIfRequested()
208
209
Conditionally suspends current thread of execution and waits until resumed
210
or canceled by the corresponding methods of QFuture. This method does not
211
block unless the computation is requested to be suspended by
212
QFuture::suspend() or another related method. If you want to check that the
213
execution has been suspended, use QFuture::isSuspended().
214
215
\note When using the same promise in multiple threads,
216
QFuture::isSuspended() becomes \c true as soon as at least one thread with
217
the promise suspends.
218
219
220
The following code snippets show the usage of suspension mechanism:
221
222
\snippet snippet_qpromise.cpp suspend_start
223
224
QFuture::suspend() requests the associated promise to suspend:
225
226
\snippet snippet_qpromise.cpp suspend_suspend
227
228
After QFuture::isSuspended() becomes \c true, you can get intermediate
229
results:
230
231
\snippet snippet_qpromise.cpp suspend_intermediateResults
232
233
When suspended, you can resume or cancel the awaiting computation:
234
235
\snippet snippet_qpromise.cpp suspend_end
236
237
238
\sa QFuture::resume(), QFuture::cancel(), QFuture::setSuspended(),
239
QFuture::toggleSuspended()
240
*/
241
242
/*! \fn template<typename T> bool QPromise<T>::isCanceled() const
243
244
Returns whether the computation has been canceled with the
245
QFuture::cancel() function. The returned value \c true indicates that the
246
computation should be finished and finish() called.
247
248
\note After cancellation, results currently available may still be accessed
249
by a future, but new results will not be added when calling addResult().
250
*/
251
252
/*! \fn template<typename T> void QPromise<T>::setProgressRange(int minimum, int maximum)
253
254
Sets the progress range of the computation to be between \a minimum and \a
255
maximum.
256
257
If \a maximum is smaller than \a minimum, \a minimum becomes the only
258
legal value.
259
260
The progress value is reset to be \a minimum.
261
262
The progress range usage can be disabled by using setProgressRange(0, 0).
263
In this case progress value is also reset to 0.
264
265
\sa QFuture::progressMinimum(), QFuture::progressMaximum(),
266
QFuture::progressValue()
267
*/
268
269
/*! \fn template<typename T> void QPromise<T>::setProgressValue(int progressValue)
270
271
Sets the progress value of the computation to \a progressValue. It is
272
possible to only increment the progress value. This is a convenience method
273
for calling setProgressValueAndText(progressValue, QString()).
274
275
In case of the \a progressValue falling out of the progress range,
276
this method has no effect.
277
278
\sa QFuture::progressValue(), setProgressRange()
279
*/
280
281
/*! \fn template<typename T> void QPromise<T>::setProgressValueAndText(int progressValue, const QString &progressText)
282
283
Sets the progress value and the progress text of the computation to \a
284
progressValue and \a progressText respectively. It is possible to only
285
increment the progress value.
286
287
\note This function has no effect if the promise is in canceled or finished
288
state.
289
290
\sa QFuture::progressValue(), QFuture::progressText(), QFuture::cancel(),
291
finish()
292
*/
293
294
/*! \fn template<typename T> void QPromise<T>::swap(QPromise<T> &other) noexcept
295
\memberswap{promise}
296
*/
qtbase
src
corelib
thread
qpromise.qdoc
Generated on
for Qt by
1.16.1