QFuture Class

template <typename T> class QFuture

QFuture 클래스는 비동기 계산의 결과를 나타냅니다. 더 보기...

헤더: #include <QFuture>
CMake: find_package(Qt6 REQUIRED COMPONENTS Core)
target_link_libraries(mytarget PRIVATE Qt6::Core)
qmake: QT += core

참고: 이 클래스의 모든 함수는 다음과 같은 예외를 제외하고 스레드 안전합니다:

공용 형

공용 함수

QFuture()
QFuture(const QFuture<T> &other)
~QFuture()
QFuture<T>::const_iterator begin() const
void cancel()
QFuture<T>::const_iterator constBegin() const
QFuture<T>::const_iterator constEnd() const
QFuture<T>::const_iterator end() const
bool isCanceled() const
bool isFinished() const
bool isResultReadyAt(int index) const
bool isRunning() const
bool isStarted() const
(since 6.0) bool isSuspended() const
(since 6.0) bool isSuspending() const
(since 6.0) bool isValid() const
(since 6.0) QFuture<T> onCanceled(Function &&handler)
(since 6.1) QFuture<T> onCanceled(QObject *context, Function &&handler)
(since 6.0) QFuture<T> onFailed(Function &&handler)
(since 6.1) QFuture<T> onFailed(QObject *context, Function &&handler)
int progressMaximum() const
int progressMinimum() const
QString progressText() const
int progressValue() const
T result() const
T resultAt(int index) const
int resultCount() const
QList<T> results() const
void resume()
(since 6.0) void setSuspended(bool suspend)
(since 6.0) void suspend()
(since 6.0) T takeResult()
(since 6.0) QFuture<QFuture<T>::ResultType<Function>> then(Function &&function)
(since 6.1) QFuture<QFuture<T>::ResultType<Function>> then(QObject *context, Function &&function)
(since 6.0) QFuture<QFuture<T>::ResultType<Function>> then(QThreadPool *pool, Function &&function)
(since 6.0) QFuture<QFuture<T>::ResultType<Function>> then(QtFuture::Launch policy, Function &&function)
(since 6.0) void toggleSuspended()
(since 6.4) QFuture<U> unwrap()
void waitForFinished()
QFuture<T> &operator=(const QFuture<T> &other)

상세 설명

QFuture를 사용하면 나중에 준비될 하나 이상의 결과에 대해 스레드를 동기화할 수 있습니다. 결과는 기본, 복사 및 이동 생성자가 있는 모든 유형이 될 수 있습니다. result (), resultAt(), results() 및 takeResult() 함수를 호출할 때 결과를 사용할 수 없는 경우 QFuture는 결과를 사용할 수 있게 될 때까지 기다립니다. isResultReadyAt () 함수를 사용하여 결과가 준비되었는지 여부를 확인할 수 있습니다. 둘 이상의 결과를 보고하는 QFuture 객체의 경우 resultCount() 함수는 연속된 결과의 수를 반환합니다. 즉, 0에서 resultCount()까지 결과를 반복해도 항상 안전합니다. takeResult()는 퓨처를 무효화하며, 이후 퓨처의 결과 또는 결과에 액세스하려는 모든 시도는 정의되지 않은 동작으로 이어집니다. isValid()는 결과에 액세스할 수 있는지 여부를 알려줍니다.

QFuture는 Java 스타일 이터레이터 (QFutureIterator)와 STL 스타일 이터레이터 (QFuture::const_iterator)를 제공합니다. 이러한 이터레이터를 사용하는 것은 향후 결과에 액세스하는 또 다른 방법입니다.

한 비동기 계산의 결과를 다른 비동기 계산으로 전달해야 하는 경우 QFuture는 then()를 사용하여 여러 개의 순차 계산을 연결하는 편리한 방법을 제공합니다. onCanceled()는 QFuture가 취소될 경우 호출할 핸들러를 추가하는 데 사용할 수 있습니다. 또한 onFailed()는 체인에서 발생한 모든 오류를 처리하는 데 사용할 수 있습니다. QFuture는 오류 처리를 위해 예외에 의존한다는 점에 유의하세요. 예외를 사용할 수 없는 경우에도 오류 유형을 QFuture 유형의 일부로 만들어 QFuture의 오류 상태를 나타낼 수 있습니다. 예를 들어, 결과 또는 실패를 유지하기 위해 std::variant, std::any 또는 이와 유사한 것을 사용하거나 사용자 지정 유형을 만들 수 있습니다.

아래 예제는 예외를 사용하지 않고 오류를 처리하는 방법을 보여줍니다. 네트워크 위치에서 대용량 파일을 가져오기 위해 네트워크 요청을 보내려고 한다고 가정해 보겠습니다. 그런 다음 파일 시스템에 파일을 쓰고 성공할 경우 해당 위치를 반환하려고 합니다. 이 두 작업은 서로 다른 오류와 함께 실패할 수 있습니다. 따라서 std::variant 을 사용하여 결과 또는 오류를 보관합니다:

using NetworkReply = std::variant<QByteArray, QNetworkReply::NetworkError>;

enum class IOError { FailedToRead, FailedToWrite };
using IOResult = std::variant<QString, IOError>;

그리고 then()를 사용하여 두 작업을 결합합니다:

QFuture<IOResult> future = QtConcurrent::run([url] {
        ...
        return NetworkReply(QNetworkReply::TimeoutError);
}).then([](NetworkReply reply) {
    if (auto error = std::get_if<QNetworkReply::NetworkError>(&reply))
        return IOResult(IOError::FailedToRead);

    auto data = std::get_if<QByteArray>(&reply);
    // try to write *data and return IOError::FailedToWrite on failure
    ...
});

auto result = future.result();
if (auto filePath = std::get_if<QString>(&result)) {
    // do something with *filePath
else
    // process the error

여러 개의 연속과 핸들러를 어떤 순서로든 연결할 수 있습니다. 예를 들어

QFuture<int> testFuture = ...;
auto resultFuture = testFuture.then([](int res) {
    // Block 1
}).onCanceled([] {
    // Block 2
}).onFailed([] {
    // Block 3
}).then([] {
    // Block 4
}).onFailed([] {
    // Block 5
}).onCanceled([] {
    // Block 6
});

testFuture 의 상태(취소됨, 예외 있음, 결과 있음)에 따라 다음 onCanceled(), onFailed() 또는 then()가 호출됩니다. 따라서 testFuture 이 성공적으로 완료되면 Block 1 이 호출됩니다. 이것도 성공하면 다음 then() (Block 4)가 호출됩니다. testFuture 가 취소되거나 예외로 실패하면 Block 2 또는 Block 3 가 각각 호출됩니다. 이후 다음 then()가 호출되고 스토리가 반복됩니다.

참고: Block 2 가 호출되어 예외가 발생하면 다음 onFailed() (Block 3)가 예외를 처리합니다. onFailed ()와 onCanceled()의 순서가 뒤바뀌면 예외 상태가 다음 연속으로 전파되어 결국 Block 5 에서 잡히게 됩니다.

다음 예제에서는 첫 번째 onCanceled() (Block 2)가 제거됩니다:

QFuture<int> testFuture = ...;
auto resultFuture = testFuture.then([](int res) {
    // Block 1
}).onFailed([] {
    // Block 3
}).then([] {
    // Block 4
}).onFailed([] {
    // Block 5
}).onCanceled([] {
    // Block 6
});

testFuture 가 취소되면 그 상태는 다음 then()로 전파되며, 이 역시 취소됩니다. 따라서 이 경우 Block 6 이 호출됩니다.

미래에는 하나의 연속만 있을 수 있습니다. 다음 예를 살펴보세요:

QPromise<int> p;

QFuture<int> f1 = p.future();
f1.then([](int) { qDebug("first"); });

QFuture<int> f2 = p.future();
f2.then([](int) { qDebug("second"); });

p.start();
p.addResult(42);
p.finish();

이 경우 f1f2 은 동일한 내부 상태를 공유하므로 사실상 동일한 QFuture 객체입니다. 따라서 f2 에서 then 을 호출하면 f1 에 지정된 연속을 덮어쓰게 됩니다. 따라서 이 코드가 실행될 때 "second" 만 인쇄됩니다.

QFuture는 실행 중인 계산과 상호 작용하는 방법도 제공합니다. 예를 들어 cancel() 함수를 사용하여 계산을 취소할 수 있습니다. 계산을 일시 중단하거나 다시 시작하려면 setSuspended() 함수 또는 suspend(), resume() 또는 toggleSuspended() 편의 함수 중 하나를 사용합니다. 실행 중인 모든 비동기 계산을 취소하거나 일시 중단할 수 있는 것은 아니라는 점에 유의하세요. 예를 들어, QtConcurrent::run()이 반환하는 미래는 취소할 수 없지만, QtConcurrent::mappedReduced()가 반환하는 미래는 취소할 수 있습니다.

진행 정보는 progressValue(), progressMinimum(), progressMaximum(), progressText() 함수에 의해 제공됩니다. waitForFinished () 함수는 호출 스레드를 차단하고 계산이 완료될 때까지 대기하여 모든 결과를 사용할 수 있도록 합니다.

QFuture로 표시되는 계산 상태는 isCanceled(), isStarted(), isFinished(), isRunning(), isSuspending() 또는 isSuspended() 함수를 사용하여 쿼리할 수 있습니다.

QFuture<void>는 결과 가져오기 함수를 포함하지 않도록 특화되어 있습니다. 모든 QFuture<T>도 QFuture<void>에 할당하거나 복사할 수 있습니다. 이는 실제 결과 데이터가 아닌 상태 또는 진행률 정보만 필요한 경우에 유용합니다.

신호 및 슬롯을 사용하여 실행 중인 작업과 상호 작용하려면 QFutureWatcher 을 사용합니다.

QtFuture::connect()를 사용하여 신호가 방출될 때 해결될 QFuture 객체에 신호를 연결할 수도 있습니다. 이렇게 하면 QFuture 객체와 같이 신호로 작업할 수 있습니다. 예를 들어 then()와 결합하면 동일한 스레드 또는 새 스레드에서 호출되는 신호에 여러 개의 연속을 연결할 수 있습니다.

QtFuture::whenAll() 및 QtFuture::whenAny() 함수는 여러 개의 퓨처를 결합하여 마지막 또는 첫 번째 퓨처가 완료되는 시점을 추적하는 데 사용할 수 있습니다.

편의 함수 QtFuture::makeReadyVoidFuture(), QtFuture::makeReadyValueFuture(), QtFuture::makeReadyRangeFuture() 및 QtFuture::makeExceptionalFuture()를 사용하여 값이 있는 준비된 QFuture 객체 또는 예외를 보유한 QFuture 객체를 만들 수 있습니다.

참고: 일부 API( QFuture::then() 또는 다양한 QtConcurrent 메서드 오버로드 참조)에서는 특정 스레드 풀로 계산을 예약할 수 있습니다. 그러나 QFuture는 교착 상태를 방지하고 스레드 사용을 최적화하기 위해 작업 훔치기 알고리즘을 구현합니다. 따라서 QFuture의 결과를 요청하는 스레드에서 직접 계산을 실행할 수 있습니다.

참고: 계산을 시작하고 그 결과를 QFuture에 저장하려면 QPromise 또는 Qt Concurrent 프레임워크 중 하나를 사용합니다.

QPromise, QtFuture::connect(), QtFuture::makeReadyVoidFuture(), QtFuture::makeReadyValueFuture(), QtFuture::makeReadyRangeFuture(), QtFuture::makeExceptionalFuture(), QFutureWatcher, 및 Qt Concurrent.

멤버 유형 문서

QFuture::ConstIterator

QFuture::const_iterator 의 Qt 스타일 동의어.

멤버 함수 문서

QFuture::QFuture()

취소된 비어 있는 미래를 구성합니다.

QFuture::QFuture(const QFuture<T> &other)

other 의 복사본을 생성합니다.

operator=()도 참조하세요 .

QFuture::~QFuture()

미래를 파괴합니다.

비동기 계산을 기다리거나 취소하지 않는다는 점에 유의하세요. 미래가 파괴되기 전에 계산이 완료되었는지 확인해야 하는 경우 waitForFinished() 또는 QFutureSynchronizer 을 사용하세요.

template <typename U = T, typename = QtPrivate::EnableForNonVoid<U>> QFuture<T>::const_iterator QFuture::begin() const

미래의 첫 번째 결과를 가리키는 상수 STL 스타일 이터레이터를 반환합니다.

constBegin() 및 end()도 참조하세요 .

void QFuture::cancel()

이 미래로 표시되는 비동기 계산을 취소합니다. 취소는 비동기식이라는 점에 유의하세요. 동기식 취소가 필요한 경우 취소() 호출 후 waitForFinished()를 사용하세요.

현재 사용 가능한 결과는 취소된 미래에서도 계속 액세스할 수 있지만 이 함수를 호출한 후에는 새 결과를 사용할 수 없게 됩니다. 이 미래를 보고 있는 QFutureWatcher 객체는 취소된 미래에 진행 상황 및 결과 준비 신호를 전달하지 않습니다.

실행 중인 모든 비동기 계산을 취소할 수 있는 것은 아니라는 점에 유의하세요. 예를 들어, QtConcurrent::run()이 반환한 퓨처는 취소할 수 없지만, QtConcurrent::mappedReduced()가 반환한 퓨처는 취소할 수 있습니다.

template <typename U = T, typename = QtPrivate::EnableForNonVoid<U>> QFuture<T>::const_iterator QFuture::constBegin() const

미래의 첫 번째 결과를 가리키는 상수 STL 스타일 이터레이터를 반환합니다.

begin() 및 constEnd()도 참조하세요 .

template <typename U = T, typename = QtPrivate::EnableForNonVoid<U>> QFuture<T>::const_iterator QFuture::constEnd() const

미래의 마지막 결과 이후의 가상의 결과를 가리키는 상수 STL 스타일 이터레이터를 반환합니다.

constBegin() 및 end()도 참조하세요 .

template <typename U = T, typename = QtPrivate::EnableForNonVoid<U>> QFuture<T>::const_iterator QFuture::end() const

미래의 마지막 결과 이후의 가상의 결과를 가리키는 상수 STL 스타일 이터레이터를 반환합니다.

begin() 및 constEnd()도 참조하세요 .

bool QFuture::isCanceled() const

비동기 계산이 cancel() 함수로 취소된 경우 true 를 반환하고, 그렇지 않으면 false 를 반환합니다.

이 함수가 true 을 반환하더라도 계산이 계속 실행 중일 수 있다는 점에 유의하세요. 자세한 내용은 cancel()를 참조하세요.

bool QFuture::isFinished() const

이 미래로 표현된 비동기 계산이 완료되면 true 을 반환하고, 그렇지 않으면 false 을 반환합니다.

template <typename U = T, typename = QtPrivate::EnableForNonVoid<U>> bool QFuture::isResultReadyAt(int index) const

index 의 결과를 즉시 사용할 수 있으면 true 을 반환하고, 그렇지 않으면 false 을 반환합니다.

참고: isValid()가 QFuture 에 대해 false 을 반환하는 경우 isResultReadyAt()을 호출하면 정의되지 않은 동작이 발생합니다.

resultAt(), resultCount() 및 takeResult()도 참조하세요 .

bool QFuture::isRunning() const

이 미래가 나타내는 비동기 계산이 현재 실행 중이면 true 을 반환하고, 그렇지 않으면 false 을 반환합니다.

bool QFuture::isStarted() const

이 미래로 표시되는 비동기 계산이 시작되면 true 을 반환하고, 그렇지 않으면 false 을 반환합니다.

[since 6.0] bool QFuture::isSuspended() const

비동기 계산의 일시 중지가 요청되었고, 더 이상 결과나 진행 상황의 변경이 예상되지 않는다는 의미로 유효할 경우 true 을 반환합니다.

이 함수는 Qt 6.0에 도입되었습니다.

setSuspended(), toggleSuspended() 및 isSuspending()도 참조하십시오 .

[since 6.0] bool QFuture::isSuspending() const

비동기 계산이 suspend() 함수로 일시 중단되었지만 아직 작업이 일시 중단되지 않았고 계산이 계속 실행 중인 경우 true 을 반환합니다. 그렇지 않으면 false 을 반환합니다.

일시 중단이 실제로 적용되고 있는지 확인하려면 isSuspended() 대신 사용하세요.

이 함수는 Qt 6.0에 도입되었습니다.

setSuspended(), toggleSuspended() 및 isSuspended()도 참조하십시오 .

[since 6.0] bool QFuture::isValid() const

QFuture 객체에서 하나 이상의 결과에 액세스하거나 결과를 가져올 수 있으면 true 을 반환합니다. 미래에서 결과를 가져온 후에는 false를 반환합니다.

이 함수는 Qt 6.0에 도입되었습니다.

takeResult(), result(), results() 및 resultAt()도 참조하세요 .

[since 6.0] template <typename Function, typename = std::enable_if_t<std::is_invocable_r_v<T, Function>>> QFuture<T> QFuture::onCanceled(Function &&handler)

이 퓨처에 취소 handler 를 첨부합니다. 반환된 퓨처는 이 퓨처가 취소되지 않는 한 이 퓨처와 정확히 동작합니다(동일한 상태와 결과를 가짐). handler 은 인수를 받지 않고 이 퓨처가 패키징한 타입의 값을 반환하는 콜러블입니다. 취소 후 반환된 퓨처는 handler 에서 반환한 값을 패키징합니다.

취소 전에 첨부된 경우, 취소 후 완료된 것으로 퓨처를 보고하는 동일한 스레드에서 handler 가 호출됩니다. 이 퓨처가 이미 취소된 후에 핸들러가 첨부되면 onCanceled() 을 실행하는 스레드에서 즉시 호출됩니다. 따라서 핸들러는 항상 어떤 스레드에서 실행될지 가정할 수 없습니다. 처리기가 어떤 스레드에서 호출되는지 제어하려면 컨텍스트 객체를 받는 오버로드를 사용하세요.

아래 예는 취소 처리기를 첨부하는 방법을 보여줍니다:

QFuture<int> testFuture = ...;
auto resultFuture = testFuture.then([](int res) {
    // Block 1
    ...
    return 1;
}).then([](int res) {
    // Block 2
    ...
    return 2;
}).onCanceled([] {
    // Block 3
    ...
    return -1;
});

testFuture 가 취소되면 Block 3 가 호출되고 resultFuture 는 그 결과로 -1 를 갖게 됩니다. testFuture 와는 달리 Canceled 상태가 되지 않습니다. 즉, 결과를 가져오고 카운트다운을 첨부하는 등의 작업을 할 수 있습니다.

또한 연속 체인이 실행되는 동안 체인을 시작한 퓨처를 통해 연속 체인을 취소할 수 있다는 점에 유의하세요. Block 1 이 이미 실행되고 있는 동안 testFuture.cancel() 이 호출되었다고 가정해 보겠습니다. 다음 연속은 취소가 요청되었음을 감지하여 Block 2 을 건너뛰고 취소 핸들러(Block 3)를 호출합니다.

참고: 이 메서드는 연속 체인의 결과를 나타내는 새로운 QFuture 을 반환합니다. 결과인 QFuture 자체를 취소해도 이어지는 체인에서 취소 처리기는 호출되지 않습니다. 즉, resultFuture.cancel() 을 호출하면 Block 3 은 호출되지 않습니다. resultFuturetestFuture 에 취소 핸들러를 연결한 결과의 미래이므로 resultFuture 자체에는 취소 핸들러가 연결되지 않았기 때문입니다. testFuture 의 취소 또는 onCancelled() 호출 전에 연결된 연속에 의해 반환된 퓨처만 Block 3 를 트리거할 수 있습니다.

이 함수는 Qt 6.0에 도입되었습니다.

then() 및 onFailed()도 참조하십시오 .

[since 6.1] template <typename Function, typename = std::enable_if_t<std::is_invocable_r_v<T, Function>>> QFuture<T> QFuture::onCanceled(QObject *context, Function &&handler)

과부하가 걸린 함수입니다.

이 퓨처에 취소 handler 를 첨부하여 퓨처가 취소될 때 호출합니다. handler 은 인수를 받지 않는 콜러블입니다. context 객체의 스레드에서 호출됩니다. 특정 스레드에서 취소를 처리해야 하는 경우 유용할 수 있습니다.

체인이 완료되기 전에 context 가 파괴되면 미래가 취소됩니다. 자세한 내용은 then()를 참조하세요.

참고: 이 메서드를 호출할 때는 체인을 설정하는 동안 context 이 살아 있는지 확인해야 합니다.

handler 에 대한 자세한 내용은 다른 오버로드 문서를 참조하세요.

이 함수는 Qt 6.1에 도입되었습니다.

then() 및 onFailed()도 참조하세요 .

[since 6.0] template <typename Function, typename = std::enable_if_t<!QtPrivate::ArgResolver<Function>::HasExtraArgs>> QFuture<T> QFuture::onFailed(Function &&handler)

예외를 처리하기 위해 이 퓨처에 실패 핸들러를 첨부합니다. 반환된 퓨처는 이 퓨처가 예외로 실패하지 않는 한 이 퓨처와 정확히 동작합니다(동일한 상태와 결과를 가짐).

handler 은 인수가 없거나 하나의 인수를 받아 catch 문과 유사하게 특정 오류 유형별로 필터링하는 콜러블입니다. 이 퓨처가 패키징한 유형의 값을 반환합니다. 실패 후 반환된 퓨처는 handler 에서 반환한 값을 패키징합니다.

핸들러는 예외가 발생한 경우에만 호출됩니다. 이 핸들러가 첨부된 후에 예외가 발생하면 예외의 결과로 퓨처가 완료된 것으로 보고하는 스레드에서 핸들러가 실행됩니다. 이 퓨처가 이미 실패한 후에 핸들러가 첨부되면 onFailed() 을 실행하는 스레드에서 즉시 호출됩니다. 따라서 처리기는 항상 어떤 스레드에서 실행될지 가정할 수 없습니다. 처리기가 어떤 스레드에서 호출되는지 제어하려면 컨텍스트 객체를 받는 오버로드를 사용하세요.

아래 예제는 장애 처리기를 첨부하는 방법을 보여줍니다:

QFuture<int> future = ...;
auto resultFuture = future.then([](int res) {
    ...
    throw Error();
    ...
}).onFailed([](const Error &e) {
    // Handle exceptions of type Error
    ...
    return -1;
}).onFailed([] {
    // Handle all other types of errors
    ...
    return -1;
});

auto result = resultFuture.result(); // result is -1

처리기가 여러 개 첨부되어 있는 경우 던져진 예외 유형과 일치하는 첫 번째 처리기가 호출됩니다. 예를 들어

QFuture<int> future = ...;
future.then([](int res) {
    ...
    throw std::runtime_error("message");
    ...
}).onFailed([](const std::exception &e) {
    // This handler will be invoked
}).onFailed([](const std::runtime_error &e) {
    // This handler won't be invoked, because of the handler above.
});

처리기 중 던져진 예외 유형과 일치하는 처리기가 없는 경우 예외는 나중에 발생한 예외로 전파됩니다:

QFuture<int> future = ...;
auto resultFuture = future.then([](int res) {
    ...
    throw Error("message");
    ...
}).onFailed([](const std::exception &e) {
    // Won't be invoked
}).onFailed([](const QException &e) {
    // Won't be invoked
});

try {
    auto result = resultFuture.result();
} catch(...) {
    // Handle the exception
}

참고: 인자를 받지 않는 핸들러를 항상 첨부하여 모든 예외 유형을 처리하고 try-catch 블록을 작성하지 않을 수 있습니다.

이 함수는 Qt 6.0에 도입되었습니다.

then() 및 onCanceled()도 참조하십시오 .

[since 6.1] template <typename Function, typename = std::enable_if_t<!QtPrivate::ArgResolver<Function>::HasExtraArgs>> QFuture<T> QFuture::onFailed(QObject *context, Function &&handler)

오버로드된 함수입니다.

이 퓨처에 오류 처리기를 첨부하여 퓨처가 발생하거나 이미 발생시킨 예외를 처리합니다. 이 퓨처와 같은 유형의 QFuture 을 반환합니다. 처리기는 예외가 발생한 경우에만 context 객체의 스레드에서 호출됩니다. 특정 스레드에서 오류를 처리해야 하는 경우 유용할 수 있습니다. 예를 들어

// somewhere in the main thread
auto future = QtConcurrent::run([] {
    // This will run in a separate thread
    ...
    throw std::exception();
}).onFailed(this, [] {
   // Update UI elements
});

QtConcurrent::run 에 첨부된 오류 처리기는 UI 요소를 업데이트하므로 GUI가 아닌 스레드에서는 호출할 수 없습니다. 따라서 this.onFailed() 에 컨텍스트로 제공되어 메인 스레드에서 호출될 수 있도록 합니다.

체인이 완료되기 전에 context 이 파괴되면 미래가 취소됩니다. 자세한 내용은 then()를 참조하세요.

참고: 이 메서드를 호출할 때는 체인을 설정하는 동안 context 이 살아 있는지 확인해야 합니다.

handler 에 대한 자세한 내용은 다른 오버로드 문서를 참조하세요.

이 함수는 Qt 6.1에 도입되었습니다.

then() 및 onCanceled()도 참조하세요 .

int QFuture::progressMaximum() const

최대 progressValue()를 반환합니다.

progressValue() 및 progressMinimum()도 참조하세요 .

int QFuture::progressMinimum() const

최소 progressValue()를 반환합니다.

progressValue() 및 progressMaximum()도 참조하십시오 .

QString QFuture::progressText() const

비동기 계산에서 보고된 진행률의 (선택 사항) 텍스트 표현을 반환합니다.

모든 계산이 진행 상황을 텍스트로 표현하는 것은 아니므로 이 함수는 빈 문자열을 반환할 수 있다는 점에 유의하세요.

int QFuture::progressValue() const

progressMinimum()와 progressMaximum() 사이에 있는 현재 진행률 값을 반환합니다.

progressMinimum() 및 progressMaximum()도 참조하세요 .

template <typename U = T, typename = QtPrivate::EnableForNonVoid<U>> T QFuture::result() const

향후 첫 번째 결과를 반환합니다. 결과를 즉시 사용할 수 없는 경우 이 함수는 결과를 차단하고 사용할 수 있을 때까지 기다립니다. resultAt (0)을 호출할 때 편리하게 사용할 수 있는 방법입니다. result() 은 내부적으로 저장된 결과의 사본을 반환합니다. T 이 이동 전용 유형이거나 결과를 복사하지 않으려면 takeResult()을 대신 사용하세요.

result() 참고: isValid()이 false 를 반환하는 경우 QFuture 를 호출하면 정의되지 않은 동작이 발생합니다.

resultAt(), results() 및 takeResult()도 참조하세요 .

template <typename U = T, typename = QtPrivate::EnableForNonVoid<U>> T QFuture::resultAt(int index) const

나중에 index 에서 결과를 반환합니다. 결과를 즉시 사용할 수 없는 경우 이 함수는 차단하고 결과를 사용할 수 있을 때까지 기다립니다.

참고: isValid()가 QFuture 에 대해 false 을 반환하는 경우 resultAt()을 호출하면 정의되지 않은 동작이 발생합니다.

result(), results(), takeResult() 및 resultCount()도 참조하세요 .

int QFuture::resultCount() const

이 미래에 사용할 수 있는 연속 결과의 수를 반환합니다. 결과 집합의 간격으로 인해 저장된 실제 결과 수는 이 값과 다를 수 있습니다. 0에서 resultCount()까지 결과를 반복하는 것이 항상 안전합니다.

result(), resultAt(), results() 및 takeResult()도 참조하세요 .

template <typename U = T, typename = QtPrivate::EnableForNonVoid<U>> QList<T> QFuture::results() const

미래의 모든 결과를 반환합니다. 결과를 즉시 사용할 수 없는 경우 이 함수는 결과를 차단하고 사용할 수 있게 될 때까지 기다립니다. results() 은 내부에 저장된 결과의 사본을 반환합니다. 이동 전용 유형 T 의 모든 결과 가져오기는 현재 지원되지 않습니다. 그러나 STL 스타일 이터레이터 또는 읽기 전용 Java 스타일 이터레이터를 사용하여 이동 전용 결과 목록을 계속 반복할 수 있습니다.

참고: isValid()이 QFuture 에 대해 false 을 반환하는 경우 results() 을 호출하면 정의되지 않은 동작이 발생합니다.

result(), resultAt(), takeResult(), resultCount() 및 isValid()도 참조하세요 .

void QFuture::resume()

future()로 표현되는 비동기 계산을 재개합니다. setSuspended (false)를 호출하기만 하면 되는 편리한 메서드입니다.

suspend()도 참조하세요 .

[since 6.0] void QFuture::setSuspended(bool suspend)

suspend 가 참이면 이 함수는 future()로 표현되는 비동기 계산을 일시 중단합니다. 계산이 이미 일시 중단된 경우 이 함수는 아무 작업도 수행하지 않습니다. QFutureWatcher 미래가 일시 중단되면 진행률 및 결과 준비 신호 전달을 즉시 중단하지 않습니다. 일시 중단하는 순간에도 여전히 진행 중이며 중지할 수 없는 계산이 있을 수 있습니다. 이러한 계산에 대한 신호는 계속 전달됩니다.

suspend 이 거짓이면 이 함수는 비동기 계산을 재개합니다. 이전에 계산이 일시 중단되지 않은 경우 이 함수는 아무 작업도 수행하지 않습니다.

모든 계산이 일시 중단될 수 있는 것은 아니라는 점에 유의하세요. 예를 들어, QtConcurrent::run()이 반환하는 QFuture 은 일시 중단할 수 없지만, QtConcurrent::mappedReduced()가 반환하는 QFuture 은 일시 중단할 수 있습니다.

이 함수는 Qt 6.0에 도입되었습니다.

isSuspended(), suspend(), resume() 및 toggleSuspended()도 참조하십시오 .

[since 6.0] void QFuture::suspend()

이 미래로 표현되는 비동기 계산을 일시 중단합니다. setSuspended (참)을 호출하기만 하면 되는 편리한 메서드입니다.

이 함수는 Qt 6.0에 도입되었습니다.

resume()도 참조하십시오 .

[since 6.0] template <typename U = T, typename = QtPrivate::EnableForNonVoid<U>> T QFuture::takeResult()

isValid()가 true 을 반환하는 경우에만 이 함수를 호출하고 그렇지 않으면 동작이 정의되지 않습니다. 이 함수는 결과가 하나만 예상되는 경우 QFuture 객체에서 첫 번째 결과를 가져옵니다(이동). 다른 결과가 있으면 첫 번째 결과를 가져온 후 버려집니다. 결과를 즉시 사용할 수 없는 경우 이 함수는 결과를 차단하고 사용할 수 있게 될 때까지 기다립니다. QFuture 은 가능한 경우 이동 시맨틱을 사용하려고 시도하고, 이동이 불가능한 유형인 경우 복사 구조로 돌아갑니다. 결과를 가져온 후 isValid()는 false 으로 평가됩니다.

참고: QFuture 는 일반적으로 서로 다른 QFuture 객체 간에(그리고 잠재적으로 서로 다른 스레드 간에) 결과를 공유할 수 있습니다. takeResult()는 QFuture 가 이동 전용 유형(예: std::unique_ptr)에서도 작동하도록 하기 위해 도입되었으므로 하나의 스레드만 향후 결과를 이동하고 한 번만 수행할 수 있다고 가정합니다. 또한 모든 결과의 목록을 가져오는 것은 현재 지원되지 않습니다. 그러나 STL 스타일 이터레이터 또는 읽기 전용 Java 스타일 이터레이터를 사용하여 이동 전용 결과 목록을 계속 반복할 수 있습니다.

이 기능은 Qt 6.0에 도입되었습니다.

result(), results(), resultAt() 및 isValid()도 참조하세요 .

[since 6.0] template <typename Function> QFuture<QFuture<T>::ResultType<Function>> QFuture::then(Function &&function)

이것은 오버로드된 함수입니다.

이 퓨처에 연속을 첨부하여 원하는 경우 Sync 정책을 사용하여 여러 비동기 계산을 체인으로 연결할 수 있습니다. function 이 퓨처에 결과가 있는 경우( QFuture<void>가 아닌) 이 퓨처가 패키징한 유형의 인수를 받는 호출 가능 함수가 됩니다. 그렇지 않으면 인수를 받지 않습니다. 이 메서드는 function 에서 반환한 유형의 값을 패키징하는 새로운 QFuture 을 반환합니다. 반환된 퓨처는 연결된 연속이 호출되거나 이 퓨처가 실패하거나 취소될 때까지 초기화되지 않은 상태에 있게 됩니다.

참고: 별도의 스레드에서 연속을 시작해야 하는 경우 이 메서드의 다른 오버로드를 사용하세요.

다음과 같이 여러 작업을 연결할 수 있습니다:

QFuture<int> future = ...;
future.then([](int res1){ ... }).then([](int res2){ ... })...

또는:

QFuture<void> future = ...;
future.then([](){ ... }).then([](){ ... })...

또는: 연속은 이전 미래를 나타내는 QFuture 인수를 값 대신 사용할 수도 있습니다. 예를 들어 QFuture 에 여러 개의 결과가 있고 사용자가 연속체 내에서 그 결과에 액세스하려는 경우에 유용할 수 있습니다. 또는 사용자가 여러 연속의 체인을 중단하지 않기 위해 연속 내부에서 이전 미래의 예외를 처리해야 하는 경우입니다. 예를 들어

QFuture<int> future = ...;
    future.then([](QFuture<int> f) {
        try {
            ...
            auto result = f.result();
            ...
        } catch (QException &e) {
            // handle the exception
        }
    }).then(...);

이전 퓨처에서 예외가 발생했는데 연속체 내부에서 처리되지 않으면 호출자가 예외를 처리할 수 있도록 예외가 연속체 퓨처로 전파됩니다:

QFuture<int> future = ...;
auto continuation = future.then([](int res1){ ... }).then([](int res2){ ... })...
...
// future throws an exception
try {
    auto result = continuation.result();
} catch (QException &e) {
    // handle the exception
}

이 경우 전체 연속 체인이 중단됩니다.

참고: 이 퓨처가 취소되면 연결된 연속도 취소됩니다.

이 함수는 Qt 6.0에 도입되었습니다.

onFailed() 및 onCanceled()도 참조하세요 .

[since 6.1] template <typename Function> QFuture<QFuture<T>::ResultType<Function>> QFuture::then(QObject *context, Function &&function)

과부하가 걸린 기능입니다.

이 퓨처에 연속을 첨부하여 원하는 경우 여러 비동기 계산을 연결할 수 있습니다. 이 퓨처로 표시되는 비동기 계산이 완료되면 context 객체의 스레드에서 function 가 호출됩니다. 이는 특정 스레드에서 연속을 호출해야 하는 경우에 유용할 수 있습니다. 예를 들어

// somewhere in the main thread
auto future = QtConcurrent::run([] {
    // This will run in a separate thread
    ...
}).then(this, [] {
   // Update UI elements
});

QtConcurrent::run 에 연결된 컨티뉴어는 UI 요소를 업데이트하므로 비 GUI 스레드에서는 호출할 수 없습니다. 따라서 this.then() 에 컨텍스트로 제공되어 메인 스레드에서 호출될 수 있도록 합니다.

다른 컨텍스트나 실행 정책이 지정되지 않는 한 다음 연속문도 동일한 컨텍스트에서 호출됩니다:

auto future = QtConcurrent::run([] {
    ...
}).then(this, [] {
   // Update UI elements
}).then([] {
    // This will also run in the main thread
});

이는 기본적으로 .then() 이 이전 스레드와 동일한 스레드에서 호출되기 때문입니다.

그러나 이 미래가 이미 완료된 후에 연속이 첨부되면 then() 을 실행하는 스레드에서 즉시 호출됩니다:

QObject *context = ...;
auto future = cachedResultsReady ? QtFuture::makeReadyValueFuture(result)
                                 : QtConcurrent::run([] { /* compute result */});
auto continuation = future.then(context, [] (Result result) {
    // Runs in the context's thread
}).then([] {
    // May or may not run in the context's thread
});

위의 예에서 cachedResultsReadytrue 이고 준비된 퓨처가 반환되는 경우 첫 번째 .then() 가 두 번째 가 첨부되기 전에 완료될 수 있습니다. 이 경우 현재 스레드에서 해결됩니다. 따라서 확실하지 않은 경우 컨텍스트를 명시적으로 전달하세요.

체인이 완료되기 전에 context 이 파괴되면 미래가 취소됩니다. 이는 context 이 더 이상 유효하지 않을 때 취소 핸들러가 호출될 수 있음을 의미합니다. 이를 방지하려면 contextQPointer 으로 캡처하세요:

QObject *context = ...;
auto future = ...;
auto continuation = future.then(context, [context](Result result) {
                               // ...
                           }).onCanceled([context = QPointer(context)] {
                               if (!context)
                                   return;  // context was destroyed already
                               // handle cancellation
                           });

컨텍스트 객체가 소멸되면 취소가 즉시 발생합니다. 체인의 이전 퓨처는 취소되지 않고 완료될 때까지 계속 실행됩니다.

참고: 이 메서드를 호출할 때는 체인을 설정하는 동안 context 이 살아 있는지 확인해야 합니다.

이 함수는 Qt 6.1에 도입되었습니다.

onFailed() 및 onCanceled()도 참조하세요 .

[since 6.0] template <typename Function> QFuture<QFuture<T>::ResultType<Function>> QFuture::then(QThreadPool *pool, Function &&function)

이것은 과부하 함수입니다.

이 퓨처에 연속을 첨부하여 원하는 경우 여러 비동기 연산을 연결할 수 있습니다. 이 퓨처가 나타내는 비동기 연산이 완료되면 poolfunction 가 예약됩니다.

이 함수는 Qt 6.0에 도입되었습니다.

onFailed() 및 onCanceled()도 참조하십시오 .

[since 6.0] template <typename Function> QFuture<QFuture<T>::ResultType<Function>> QFuture::then(QtFuture::Launch policy, Function &&function)

이것은 과부하 함수입니다.

이 퓨처에 연속을 첨부하여 여러 비동기 연산을 연결할 수 있습니다. 이 퓨처로 표현되는 비동기 계산이 완료되면 주어진 시작 policy 에 따라 function 이 호출됩니다. 연속의 결과를 나타내는 새로운 QFuture 이 반환됩니다.

policy 에 따라 이 퓨처와 동일한 스레드, 새 스레드에서 연속이 호출되거나 이 퓨처의 실행 정책 및 스레드 풀을 상속합니다. 시작 정책이 지정되지 않은 경우(콜러블만 사용하는 오버로드 참조) Sync 정책이 사용됩니다.

다음 예제에서는 두 연속성이 모두 새 스레드에서 호출되지만 동일한 스레드에서 호출됩니다.

QFuture<int> future = ...;
future.then(QtFuture::Launch::Async, [](int res){ ... }).then([](int res2){ ... });

다음 예에서는 두 연속이 모두 동일한 스레드 풀을 사용하여 새 스레드에서 호출됩니다.

QFuture<int> future = ...;
future.then(QtFuture::Launch::Async, [](int res){ ... })
      .then(QtFuture::Launch::Inherit, [](int res2){ ... });

function 에 대한 자세한 내용은 다른 오버로드에 대한 문서를 참조하십시오.

이 함수는 Qt 6.0에 도입되었습니다.

onFailed() 및 onCanceled()도 참조하십시오 .

[since 6.0] void QFuture::toggleSuspended()

비동기 계산의 일시 중단 상태를 전환합니다. 즉, 계산이 현재 일시 중단 중이거나 일시 중단된 경우 이 함수를 호출하면 계산이 재개되고, 계산이 실행 중인 경우 일시 중단됩니다. setSuspended (!(isSuspending() || isSuspended()))를 호출하는 편리한 방법입니다.

이 함수는 Qt 6.0에 도입되었습니다.

setSuspended(), suspend() 및 resume()도 참조하십시오 .

[since 6.4] template <typename U> QFuture<U> QFuture::unwrap()

QFuture<T> 에서 내부 퓨처를 언래핑합니다. 여기서 TQFuture<U> 타입의 퓨처, 즉 이 퓨처의 타입은 QFuture<QFuture<U>> 입니다:

QFuture<QFuture<int>> outerFuture = ...;
QFuture<int> unwrappedFuture = outerFuture.unwrap();

unwrappedFutureouterFuture 안에 중첩된 내부 퓨처가 충족되는 즉시 동일한 결과 또는 예외와 함께 내부 퓨처를 완료된 것으로 보고하는 동일한 스레드에서 충족됩니다. 내부 퓨처가 취소되면 unwrappedFuture 도 취소됩니다.

이 기능은 여러 계산을 연결하고 그 중 하나가 결과 유형으로 QFuture 을 반환할 때 특히 유용합니다. 예를 들어 URL에서 여러 이미지를 다운로드하고, 이미지의 크기를 조정한 다음 QtConcurrent::mappedReduced()를 사용하여 하나의 이미지로 축소한다고 가정해 봅시다. 다음과 같이 작성할 수 있습니다:

auto downloadImages = [] (const QUrl &url) {
    QList<QImage> images;
    ...
    return images;
};

auto processImages = [](const QList<QImage> &images) {
   return QtConcurrent::mappedReduced(images, scale, reduceImages);
}

auto show = [](const QImage &image) { ... };

auto future = QtConcurrent::run(downloadImages, url)
               .then(processImages)
               .unwrap()
               .then(show);

여기서 QtConcurrent::mappedReduced()QFuture<QImage> 을 반환하므로 .then(processImages)QFuture<QFuture<QImage>> 를 반환합니다. show()QImage 를 인수로 받기 때문에 .then(processImages) 의 결과를 직접 전달할 수 없습니다. .unwrap() 을 호출해야 하며, 이 호출은 내부 퓨처가 준비되면 결과를 가져와 다음 연속으로 전달합니다.

다중 중첩의 경우 .unwrap() 은 가장 안쪽 레벨로 내려갑니다:

QFuture<QFuture<QFuture<int>>>> outerFuture;
QFuture<int> unwrappedFuture = outerFuture.unwrap();

이 함수는 Qt 6.4에 도입되었습니다.

void QFuture::waitForFinished()

비동기 계산이 완료될 때까지( cancel()의 계산 포함), 즉 isFinished()가 true 을 반환할 때까지 기다립니다.

QFuture<T> &QFuture::operator=(const QFuture<T> &other)

이 미래에 other 을 할당하고 이 미래에 대한 참조를 반환합니다.

© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.