このページについて

並行タスク

QtConcurrent::task は、別のスレッドでタスクを実行するための代替インターフェースを提供します。この関数の戻り値は、QFuture API を通じて取得できます。

パラメータを調整せずに、単に別のスレッドで関数を実行したい場合は、QtConcurrent::run を使用するとコード量を減らすことができます。QtConcurrent::task は、追加の設定手順が必要な場合に備えて設計されています。

この関数は、 Qt Concurrent フレームワークの一部です。

インクルードの最適化

<QtConcurrent> ヘッダーをインクルードすると、Qt Concurrent モジュール全体とQt Core モジュール全体がインクルードされるため、コンパイル時間やバイナリサイズが増加する可能性があります。QtConcurrent::task()関数を使用するには、より具体的なヘッダーをインクルードすることができます:

#include <QtConcurrentTask>

フルーエントインターフェース

QtConcurrent::task は、QtConcurrent::QTaskBuilder と呼ばれる補助クラスのインスタンスを返します。通常、このクラスのインスタンスを手動で作成する必要はありません。QtConcurrent::QTaskBuilder は、チェーン状にさまざまなタスクパラメータを調整するためのインターフェースを提供します。このアプローチは、フルーエントインターフェースとして知られています。

必要なパラメータを設定するだけで、タスクを実行できます。タスクの設定を確定するには、QtConcurrent::QTaskBuilder::spawn を呼び出す必要があります。この関数はノンブロッキング(つまり、すぐにフューチャーオブジェクトを返す)ですが、タスクが直ちに開始されることは保証されていません。QFuture およびQFutureWatcher クラスを使用して、タスクのステータスを監視できます。

以下の例や説明を参照してください。

別のスレッドでタスクを実行する

別のスレッドで関数を実行するには、QtConcurrent::QTaskBuilder::spawn を使用します:

QtConcurrent::task([]{ qDebug("Hello, world!"); }).spawn();

これにより、デフォルトのQThreadPool から取得した別のスレッドでラムダ関数が実行されます。

タスクへの引数の渡し方

引数付きで関数を呼び出すには、QtConcurrent::QTaskBuilder::withArguments に引数を渡します:

auto task = [](const QString &s){ qDebug() << ("Hello, " + s); };
QtConcurrent::task(std::move(task))
    .withArguments("world!")
    .spawn();

QtConcurrent::QTaskBuilder::withArguments が呼び出される時点で各引数のコピーが作成され、タスクの実行が開始される際にこれらの値がスレッドに渡されます。QtConcurrent::QTaskBuilder::withArguments の呼び出し後に引数に加えられた変更は、スレッドからは認識されません。

参照で引数を受け取る関数を実行したい場合は、std::ref/cref補助関数を使用する必要があります。これらの関数は、渡された引数の周りに薄いラッパーを作成します:

QString s("Hello, ");
QtConcurrent::task([](QString &s){ s.append("world!"); })
    .withArguments(std::ref(s))
    .spawn();

ラップされたすべてのオブジェクトが、タスクの存続期間よりも長く存続するようにしてください。タスクが、std::ref/cref でラップされたオブジェクトの存続期間を超えて存続した場合、未定義の挙動が生じる可能性があります。

タスクからの値の返却

QFuture API を使用して、タスクの結果を取得できます:

auto future = QtConcurrent::task([]{ return 42; }).spawn();
auto result = future.result(); // result == 42

QFuture::result() はブロッキング呼び出しであり、結果が利用可能になるまで待機することに注意してください。タスクの実行が完了し、結果が利用可能になった際に通知を受け取るには、QFutureWatcher を使用します。

結果を別の非同期タスクに渡したい場合は、QFuture::then() を使用して、依存関係のあるタスクのチェーンを作成できます。詳細については、QFuture のドキュメントを参照してください。

その他のAPI機能

さまざまな種類の呼び出し可能オブジェクトの使用

厳密に言えば、以下の条件を満たすあらゆる種類のタスクや引数を使用できます:

std::is_invocable_v<std::decay_t<Task>, std::decay_t<Args>...>

フリー関数を使用できます:

QVariant value(42);
auto result = QtConcurrent::task([](const QVariant &var){return qvariant_cast<int>(var);})
                  .withArguments(value)
                  .spawn()
                  .result(); // result == 42

メンバ関数を使用できます:

QString result("Hello, world!");

QtConcurrent::task(&QString::chop)
    .withArguments(&result, 8)
    .spawn()
    .waitForFinished(); // result == "Hello"

operator() を持つコール可能オブジェクトを使用できます:

auto result = QtConcurrent::task(std::plus<int>())
                  .withArguments(40, 2)
                  .spawn()
                  .result() // result == 42

既存の実行可能オブジェクトを使用する場合は、それをQtConcurrent::task にコピーまたは移動するか、std::ref/crefでラップする必要があります:

struct CallableWithState
{
    void operator()(int newState) { state = newState; }

    // ...
};

// ...

CallableWithState object;

QtConcurrent::task(std::ref(object))
   .withArguments(42)
   .spawn()
   .waitForFinished(); // The object's state is set to 42

カスタムスレッドプールの使用

カスタムスレッドプールを指定できます:

QThreadPool pool;
QtConcurrent::task([]{ return 42; }).onThreadPool(pool).spawn();

タスクの優先順位の設定

タスクの優先度を設定できます:

QtConcurrent::task([]{ return 42; }).withPriority(10).spawn();

フューチャーオブジェクトが必要ない場合は、QtConcurrent::QTaskBuilder::spawn (QtConcurrent::FutureResult::Ignore )を呼び出すことができます:

QtConcurrent::task([]{ qDebug("Hello, world!"); }).spawn(FutureResult::Ignore);

関数内にQPromise<T> & 型の追加引数を定義することで、タスクに関連付けられたプロミスオブジェクトにアクセスできます。この追加引数は関数に渡される最初の引数でなければならず、「Promiseを使用した並行実行」モードと同様に、関数はvoid型を返す必要があります。結果の報告はQPromise APIを通じて行われます:

void increment(QPromise<int> &promise, int i)
{
    promise.addResult(i + 1);
}

int result = QtConcurrent::task(&increment).withArguments(10).spawn().result(); // result == 11

© 2026 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.