diff options
Diffstat (limited to 'src/corelib/thread/qfuture.qdoc')
-rw-r--r-- | src/corelib/thread/qfuture.qdoc | 175 |
1 files changed, 143 insertions, 32 deletions
diff --git a/src/corelib/thread/qfuture.qdoc b/src/corelib/thread/qfuture.qdoc index 50ec206afd..b278d39882 100644 --- a/src/corelib/thread/qfuture.qdoc +++ b/src/corelib/thread/qfuture.qdoc @@ -118,13 +118,21 @@ combine several futures and track when the last or first of them completes. A ready QFuture object with a value or a QFuture object holding exception can - be created using convenience functions QtFuture::makeReadyFuture() and + be created using convenience functions QtFuture::makeReadyVoidFuture(), + QtFuture::makeReadyValueFuture(), QtFuture::makeReadyRangeFuture(), and QtFuture::makeExceptionalFuture(). + \note Some APIs (see \l {QFuture::then()} or various QtConcurrent method + overloads) allow scheduling the computation to a specific thread pool. + However, QFuture implements a work-stealing algorithm to prevent deadlocks + and optimize thread usage. As a result, computations can be executed + directly in the thread which requests the QFuture's result. + \note To start a computation and store results in a QFuture, use QPromise or one of the APIs in the \l {Qt Concurrent} framework. - \sa QPromise, QtFuture::connect(), QtFuture::makeReadyFuture(), + \sa QPromise, QtFuture::connect(), QtFuture::makeReadyVoidFuture(), + QtFuture::makeReadyValueFuture(), QtFuture::makeReadyRangeFuture(), QtFuture::makeExceptionalFuture(), QFutureWatcher, {Qt Concurrent} */ @@ -382,7 +390,7 @@ computations), i.e. until isFinished() returns \c true. */ -/*! \fn template <typename T> T QFuture<T>::result() const +/*! \fn template <typename T> template<typename U = T, typename = QtPrivate::EnableForNonVoid<U>> T QFuture<T>::result() const Returns the first result in the future. If the result is not immediately available, this function will block and wait for the result to become @@ -397,7 +405,7 @@ \sa resultAt(), results(), takeResult() */ -/*! \fn template <typename T> T QFuture<T>::resultAt(int index) const +/*! \fn template <typename T> template<typename U = T, typename = QtPrivate::EnableForNonVoid<U>> T QFuture<T>::resultAt(int index) const Returns the result at \a index in the future. If the result is not immediately available, this function will block and wait for the result to @@ -409,7 +417,7 @@ \sa result(), results(), takeResult(), resultCount() */ -/*! \fn template <typename T> bool QFuture<T>::isResultReadyAt(int index) const +/*! \fn template <typename T> template<typename U = T, typename = QtPrivate::EnableForNonVoid<U>> bool QFuture<T>::isResultReadyAt(int index) const Returns \c true if the result at \a index is immediately available; otherwise returns \c false. @@ -420,7 +428,7 @@ \sa resultAt(), resultCount(), takeResult() */ -/*! \fn template <typename T> QList<T> QFuture<T>::results() const +/*! \fn template <typename T> template<typename U = T, typename = QtPrivate::EnableForNonVoid<U>> QList<T> QFuture<T>::results() const Returns all results from the future. If the results are not immediately available, this function will block and wait for them to become available. Note that @@ -436,7 +444,7 @@ */ #if 0 -/*! \fn template <typename T> std::vector<T> QFuture<T>::takeResults() +/*! \fn template <typename T> template<typename U = T, typename = QtPrivate::EnableForNonVoid<U>> std::vector<T> QFuture<T>::takeResults() If isValid() returns \c false, calling this function leads to undefined behavior. takeResults() takes all results from the QFuture object and invalidates it @@ -455,7 +463,7 @@ */ #endif -/*! \fn template <typename T> std::vector<T> QFuture<T>::takeResult() +/*! \fn template <typename T> template<typename U = T, typename = QtPrivate::EnableForNonVoid<U>> std::vector<T> QFuture<T>::takeResult() \since 6.0 @@ -490,7 +498,7 @@ \sa takeResult(), result(), results(), resultAt() */ -/*! \fn template <typename T> QFuture<T>::const_iterator QFuture<T>::begin() const +/*! \fn template<typename T> template<class U = T, typename = QtPrivate::EnableForNonVoid<U>> QFuture<T>::const_iterator QFuture<T>::begin() const Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first result in the future. @@ -498,7 +506,7 @@ \sa constBegin(), end() */ -/*! \fn template <typename T> QFuture<T>::const_iterator QFuture<T>::end() const +/*! \fn template<typename T> template<class U = T, typename = QtPrivate::EnableForNonVoid<U>> QFuture<T>::const_iterator QFuture<T>::end() const Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary result after the last result in the future. @@ -506,7 +514,7 @@ \sa begin(), constEnd() */ -/*! \fn template <typename T> QFuture<T>::const_iterator QFuture<T>::constBegin() const +/*! \fn template<typename T> template<class U = T, typename = QtPrivate::EnableForNonVoid<U>> QFuture<T>::const_iterator QFuture<T>::constBegin() const Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first result in the future. @@ -514,7 +522,7 @@ \sa begin(), constEnd() */ -/*! \fn template <typename T> QFuture<T>::const_iterator QFuture<T>::constEnd() const +/*! \fn template<typename T> template<class U = T, typename = QtPrivate::EnableForNonVoid<U>> QFuture<T>::const_iterator QFuture<T>::constEnd() const Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary result after the last result in the future. @@ -605,17 +613,17 @@ Returns a pointer to the current result. */ -/*! \fn template <typename T> bool QFuture<T>::const_iterator::operator!=(const const_iterator &other) const +/*! \fn template <typename T> bool QFuture<T>::const_iterator::operator!=(const const_iterator &lhs, const const_iterator &rhs) - Returns \c true if \a other points to a different result than this iterator; + Returns \c true if \a lhs points to a different result than \a rhs iterator; otherwise returns \c false. \sa operator==() */ -/*! \fn template <typename T> bool QFuture<T>::const_iterator::operator==(const const_iterator &other) const +/*! \fn template <typename T> bool QFuture<T>::const_iterator::operator==(const const_iterator &lhs, const const_iterator &rhs) - Returns \c true if \a other points to the same result as this iterator; + Returns \c true if \a lhs points to the same result as \a rhs iterator; otherwise returns \c false. \sa operator!=() @@ -928,7 +936,7 @@ \sa QtFuture::whenAny() */ -/*! \fn template<class Sender, class Signal> static QFuture<ArgsType<Signal>> QtFuture::connect(Sender *sender, Signal signal) +/*! \fn template<class Sender, class Signal, typename = QtPrivate::EnableIfInvocable<Sender, Signal>> static QFuture<ArgsType<Signal>> QtFuture::connect(Sender *sender, Signal signal) Creates and returns a QFuture which will become available when the \a sender emits the \a signal. If the \a signal takes no arguments, a QFuture<void> is returned. If @@ -967,10 +975,11 @@ \sa QFuture, QFuture::then() */ -/*! \fn template<typename T> static QFuture<std::decay_t<T>> QtFuture::makeReadyFuture(T &&value) +/*! \fn template<typename T, typename = QtPrivate::EnableForNonVoid<T>> static QFuture<std::decay_t<T>> QtFuture::makeReadyFuture(T &&value) \since 6.1 \overload + \deprecated [6.6] Use makeReadyValueFuture() instead. Creates and returns a QFuture which already has a result \a value. The returned QFuture has a type of std::decay_t<T>, where T is not void. @@ -981,13 +990,20 @@ const int result = *f.takeResult(); // result == 42 \endcode - \sa QFuture, QtFuture::makeExceptionalFuture() + The method should be avoided because + it has an inconsistent set of overloads. From Qt 6.10 onwards, using it + in code will result in compiler warnings. + + \sa QFuture, QtFuture::makeReadyVoidFuture(), + QtFuture::makeReadyValueFuture(), QtFuture::makeReadyRangeFuture(), + QtFuture::makeExceptionalFuture() */ /*! \fn QFuture<void> QtFuture::makeReadyFuture() \since 6.1 \overload + \deprecated [6.6] Use makeReadyVoidFuture() instead. Creates and returns a void QFuture. Such QFuture can't store any result. One can use it to query the state of the computation. @@ -1001,14 +1017,21 @@ const bool finished = f.isFinished(); // finished == true \endcode + The method should be avoided because + it has an inconsistent set of overloads. From Qt 6.10 onwards, using it + in code will result in compiler warnings. + \sa QFuture, QFuture::isStarted(), QFuture::isRunning(), - QFuture::isFinished(), QtFuture::makeExceptionalFuture() + QFuture::isFinished(), QtFuture::makeReadyVoidFuture(), + QtFuture::makeReadyValueFuture(), QtFuture::makeReadyRangeFuture(), + QtFuture::makeExceptionalFuture() */ /*! \fn template<typename T> static QFuture<T> QtFuture::makeReadyFuture(const QList<T> &values) \since 6.1 \overload + \deprecated [6.6] Use makeReadyRangeFuture() instead. Creates and returns a QFuture which already has multiple results set from \a values. @@ -1020,7 +1043,42 @@ const auto results = f.results(); // results == { 1, 2, 3 } \endcode - \sa QFuture, QtFuture::makeExceptionalFuture() + The method should be avoided because + it has an inconsistent set of overloads. From Qt 6.10 onwards, using it + in code will result in compiler warnings. + + \sa QFuture, QtFuture::makeReadyVoidFuture(), + QtFuture::makeReadyValueFuture(), QtFuture::makeReadyRangeFuture(), + QtFuture::makeExceptionalFuture() +*/ + +/*! \fn template<typename T> static QFuture<std::decay_t<T>> QtFuture::makeReadyValueFuture(T &&value) + + \since 6.6 + + Creates and returns a QFuture which already has a result \a value. + The returned QFuture has a type of std::decay_t<T>, where T is not void. + The returned QFuture will already be in the finished state. + + \snippet code/src_corelib_thread_qfuture.cpp 35 + + \sa QFuture, QtFuture::makeReadyRangeFuture(), + QtFuture::makeReadyVoidFuture(), QtFuture::makeExceptionalFuture() +*/ + +/*! \fn QFuture<void> QtFuture::makeReadyVoidFuture() + + \since 6.6 + + Creates and returns a void QFuture. Such QFuture can't store any result. + One can use it to query the state of the computation. + The returned QFuture will already be in the finished state. + + \snippet code/src_corelib_thread_qfuture.cpp 36 + + \sa QFuture, QFuture::isStarted(), QFuture::isRunning(), + QFuture::isFinished(), QtFuture::makeReadyValueFuture(), + QtFuture::makeReadyRangeFuture(), QtFuture::makeExceptionalFuture() */ /*! \fn template<typename T> static QFuture<T> QtFuture::makeExceptionalFuture(const QException &exception) @@ -1040,7 +1098,8 @@ } \endcode - \sa QFuture, QException, QtFuture::makeReadyFuture() + \sa QFuture, QException, QtFuture::makeReadyVoidFuture(), + QtFuture::makeReadyValueFuture() */ /*! \fn template<typename T> static QFuture<T> QtFuture::makeExceptionalFuture(std::exception_ptr exception) @@ -1065,7 +1124,44 @@ } \endcode - \sa QFuture, QException, QtFuture::makeReadyFuture() + \sa QFuture, QException, QtFuture::makeReadyVoidFuture(), + QtFuture::makeReadyValueFuture() +*/ + +/*! \fn template<typename Container, QtFuture::if_container_with_input_iterators<Container>> static QFuture<QtFuture::ContainedType<Container>> QtFuture::makeReadyRangeFuture(Container &&container) + + \since 6.6 + \overload + + Takes an input container \a container and returns a QFuture with multiple + results of type \c ContainedType initialized from the values of the + \a container. + + \note This overload only participates in overload resolution if the + \c Container has input iterators. + + \snippet code/src_corelib_thread_qfuture.cpp 32 + \dots + \snippet code/src_corelib_thread_qfuture.cpp 34 + + \sa QFuture, QtFuture::makeReadyVoidFuture(), + QtFuture::makeReadyValueFuture(), QtFuture::makeExceptionalFuture() +*/ + +/*! \fn template<typename ValueType> static QFuture<ValueType> QtFuture::makeReadyRangeFuture(std::initializer_list<ValueType> values) + + \since 6.6 + \overload + + Returns a QFuture with multiple results of type \c ValueType initialized + from the input initializer list \a values. + + \snippet code/src_corelib_thread_qfuture.cpp 33 + \dots + \snippet code/src_corelib_thread_qfuture.cpp 34 + + \sa QFuture, QtFuture::makeReadyVoidFuture(), + QtFuture::makeReadyValueFuture(), QtFuture::makeExceptionalFuture() */ /*! \fn template<class T> template<class Function> QFuture<typename QFuture<T>::ResultType<Function>> QFuture<T>::then(Function &&function) @@ -1164,8 +1260,7 @@ Attaches a continuation to this future, allowing to chain multiple asynchronous computations if desired. When the asynchronous computation represented by this - future finishes, \a function will be invoked in a separate thread taken from the - QThreadPool \a pool. + future finishes, \a function will be scheduled on \a pool. \sa onFailed(), onCanceled() */ @@ -1205,13 +1300,23 @@ is attached. In this case it will be resolved in the current thread. Therefore, when in doubt, pass the context explicitly. + \target context_lifetime + If the \a context is destroyed before the chain has finished, the future is canceled. + This implies that a cancellation handler might be invoked when the \a context is not valid + anymore. To guard against this, capture the \a context as a QPointer: + + \snippet code/src_corelib_thread_qfuture.cpp 37 + + When the context object is destroyed, cancellation happens immediately. Previous futures in the + chain are \e {not} cancelled and keep running until they are finished. + \note When calling this method, it should be guaranteed that the \a context stays alive - throughout the execution of the chain. + during setup of the chain. \sa onFailed(), onCanceled() */ -/*! \fn template<class T> template<class Function> QFuture<T> QFuture<T>::onFailed(Function &&handler) +/*! \fn template<class T> template<class Function, typename = std::enable_if_t<!QtPrivate::ArgResolver<Function>::HasExtraArgs>> QFuture<T> QFuture<T>::onFailed(Function &&handler) \since 6.0 @@ -1254,7 +1359,7 @@ \sa then(), onCanceled() */ -/*! \fn template<class T> template<class Function> QFuture<T> QFuture<T>::onFailed(QObject *context, Function &&handler) +/*! \fn template<class T> template<class Function, typename = std::enable_if_t<!QtPrivate::ArgResolver<Function>::HasExtraArgs>> QFuture<T> QFuture<T>::onFailed(QObject *context, Function &&handler) \since 6.1 \overload @@ -1271,15 +1376,18 @@ be invoked from a non-gui thread. So \c this is provided as a context to \c .onFailed(), to make sure that it will be invoked in the main thread. + If the \a context is destroyed before the chain has finished, the future is canceled. + See \l {context_lifetime}{then()} for details. + \note When calling this method, it should be guaranteed that the \a context stays alive - throughout the execution of the chain. + during setup of the chain. See the documentation of the other overload for more details about \a handler. \sa then(), onCanceled() */ -/*! \fn template<class T> template<class Function> QFuture<T> QFuture<T>::onCanceled(Function &&handler) +/*! \fn template<class T> template<class Function, typename = std::enable_if_t<std::is_invocable_r_v<T, Function>>> QFuture<T> QFuture<T>::onCanceled(Function &&handler) \since 6.0 @@ -1324,7 +1432,7 @@ \sa then(), onFailed() */ -/*! \fn template<class T> template<class Function> QFuture<T> QFuture<T>::onCanceled(QObject *context, Function &&handler) +/*! \fn template<class T> template<class Function, typename = std::enable_if_t<std::is_invocable_r_v<T, Function>>> QFuture<T> QFuture<T>::onCanceled(QObject *context, Function &&handler) \since 6.1 \overload @@ -1334,8 +1442,11 @@ invoked in the thread of the \a context object. This can be useful if the cancellation needs to be handled in a specific thread. + If the \a context is destroyed before the chain has finished, the future is canceled. + See \l {context_lifetime}{then()} for details. + \note When calling this method, it should be guaranteed that the \a context stays alive - throughout the execution of the chain. + during setup of the chain. See the documentation of the other overload for more details about \a handler. |