並行実行
QtConcurrent::run() 関数は、別のスレッドで関数を実行します。この関数の戻り値は、QFuture API を通じて利用可能になります。
QtConcurrent::run() はオーバーロードされたメソッドです。これらのオーバーロードは、わずかに異なるモードとして考えることができます。基本モードでは、QtConcurrent::run() に渡された関数は、呼び出し元に単一の計算結果のみを報告することができます。「プロミス付き実行」モードでは、QtConcurrent::run() に渡された関数は、追加のQPromise API を利用できます。これにより、複数の結果の報告、進行状況の報告、呼び出し元からの要求による計算の一時停止、または呼び出し元の要求による計算の停止が可能になります。
この関数は、Qt Concurrent フレームワークの一部です。
インクルードの最適化
<QtConcurrent> ヘッダーをインクルードすると、Qt Concurrent モジュール全体とQt Core モジュール全体がインクルードされるため、コンパイル時間やバイナリサイズが増加する可能性があります。QtConcurrent::run()関数を使用するには、より具体的なヘッダーをインクルードすることができます:
#include <QtConcurrentRun>並行実行(基本モード)
QtConcurrent::run() に渡された関数は、その戻り値を通じて結果を報告することができます。
別のスレッドで関数を実行する
別のスレッドで関数を実行するには、QtConcurrent::run() を使用します:
extern void aFunction();
QFuture<void> future = QtConcurrent::run(aFunction);これにより、aFunction が、デフォルトのQThreadPool から取得された別のスレッドで実行されます。QFuture およびQFutureWatcher クラスを使用すると、関数の状態を監視できます。
専用のスレッドプールを使用するには、QThreadPool を最初の引数として渡します:
extern void aFunction();
QThreadPool pool;
QFuture<void> future = QtConcurrent::run(&pool, aFunction);関数への引数の渡し方
関数への引数の渡し方は、関数名の直後にQtConcurrent::run()の呼び出しに引数を追加することで行います。例えば:
extern void aFunctionWithArguments(int arg1, double arg2, const QString &string);
int integer = ...;
double floatingPoint = ...;
QString string = ...;
QFuture<void> future = QtConcurrent::run(aFunctionWithArguments, integer, floatingPoint, string);QtConcurrent::run() が呼び出される時点で各引数のコピーが作成され、スレッドが関数の実行を開始する際にこれらの値がスレッドに渡されます。QtConcurrent::run() の呼び出し後に引数に加えられた変更は、スレッドからは認識されません。
なお、QtConcurrent::run はオーバーロードされた関数の直接呼び出しをサポートしていません。たとえば、以下のコードはコンパイルできません:
void foo(int arg);
void foo(int arg1, int arg2);
...
QFuture<void> future = QtConcurrent::run(foo, 42);最も簡単な回避策は、ラムダ式を介してオーバーロードされた関数を呼び出すことです:
QFuture<void> future = QtConcurrent::run([] { foo(42); });あるいは、static_cast を使用することで、コンパイラにどのオーバーロードを選択すべきかを指定することもできます:
QFuture<void> future = QtConcurrent::run(static_cast<void(*)(int)>(foo), 42);あるいは、qOverload を使用することもできます:
QFuture<void> future = QtConcurrent::run(qOverload<int>(foo), 42);関数からの値の返却
関数からの戻り値は、QFuture を通じて取得できます:
extern QString functionReturningAString();
QFuture<QString> future = QtConcurrent::run(functionReturningAString);
...
QString result = future.result();結果が必要ない場合(例えば、関数がvoid を返す場合など)、関数オブジェクトを受け取るQThreadPool::start()のオーバーロードを使用する方が効率的です。
前述の通り、引数の渡し方は以下の通りです:
extern QString someFunction(const QByteArray &input);
QByteArray bytearray = ...;
QFuture<QString> future = QtConcurrent::run(someFunction, bytearray);
...
QString result = future.result();QFuture::result() 関数はブロックされ、結果が利用可能になるまで待機することに注意してください。関数の実行が完了し、結果が利用可能になったときに通知を受け取るには、QFutureWatcher を使用してください。
その他のAPI機能
メンバ関数の使用
QtConcurrent::run() は、メンバー関数へのポインタも受け付けます。Qt 6 では、最初の引数としてメンバー関数へのポインタを指定し、その後に const 参照またはクラスのインスタンスへのポインタを指定する必要があります。 const 参照を渡すのは、const メンバ関数を呼び出す際に役立ちます。一方、ポインタを渡すのは、インスタンスを変更する非 const メンバ関数を呼び出す際に役立ちます。
たとえば、別のスレッドでQByteArray::split()(const メンバ関数)を呼び出す場合は、次のように行います。
// call 'QList<QByteArray> QByteArray::split(char sep) const' in a separate thread
QByteArray bytearray = "hello world";
QFuture<QList<QByteArray> > future = QtConcurrent::run(&QByteArray::split, bytearray, ' ');
...
QList<QByteArray> result = future.result();非constメンバー関数を呼び出す場合は、次のように行います:
// call 'void QImage::invertPixels(InvertMode mode)' in a separate thread
QImage image = ...;
QFuture<void> future = QtConcurrent::run(&QImage::invertPixels, &image, QImage::InvertRgba);
...
future.waitForFinished();
// At this point, the pixels in 'image' have been invertedラムダ関数の使用
ラムダ関数の呼び出しは、次のように行います:
QFuture<void> future = QtConcurrent::run([=]() {
// Code in this block will run in another thread
});
...参照渡しされたオブジェクトを変更する関数を呼び出す場合は、次のように行います:
static void addOne(int &n) { ++n; }
...
int n = 42;
QtConcurrent::run(&addOne, std::ref(n)).waitForFinished(); // n == 43呼び出し可能なオブジェクトの使用方法は次のとおりです:
struct TestClass
{
void operator()(int s1) { s = s1; }
int s = 42;
};
...
TestClass o;
// Modify original object
QtConcurrent::run(std::ref(o), 15).waitForFinished(); // o.s == 15
// Modify a copy of the original object
QtConcurrent::run(o, 42).waitForFinished(); // o.s == 15
// Use a temporary object
QtConcurrent::run(TestClass(), 42).waitForFinished();
// Ill-formed
QtConcurrent::run(&o, 42).waitForFinished(); // compilation errorPromise を使った並行実行
「Run With Promise」モードでは、QtConcurrent::run()の基本モードと比較して、実行中のタスクをより細かく制御できます。これにより、実行中のタスクの進行状況の報告、複数の結果の報告、要求に応じて実行の一時停止、または呼び出し側の要求によるタスクの中止が可能になります。
必須の QPromise 引数
「Run With Promise」モードで QtConcurrent::run() に渡される関数には、QPromise<T> & 型の追加引数が求められる。ここで、T は計算結果の型であり(QtConcurrent::run() が返すQFuture<T> の型T と一致する必要がある)、例えば次のような形になる:
extern void aFunction(QPromise<void> &promise);
QFuture<void> future = QtConcurrent::run(aFunction);promise 引数は QtConcurrent::run() 関数内でインスタンス化され、その参照が呼び出されるaFunction に渡されるため、このモードで QtConcurrent::run() を呼び出す際、ユーザーがそれをインスタンス化したり、明示的に渡したりする必要はありません。
QPromise 型の追加引数は、常に関数の引数リストの先頭に配置する必要があります。例えば、次のようにします:
extern void aFunction(QPromise<void> &promise, int arg1, const QString &arg2);
int integer = ...;
QString string = ...;
QFuture<void> future = QtConcurrent::run(aFunction, integer, string);結果の報告
QtConcurrent::run()の基本モードとは対照的に、「Run With Promise」モードで QtConcurrent::run() に渡される関数は、常に void 型を返す必要があります。結果の報告は、QPromise 型の追加引数を通じて行われます。また、これにより、次のような複数の結果報告も可能になります:
void helloWorldFunction(QPromise<QString> &promise)
{
promise.addResult("Hello");
promise.addResult("world");
}
QFuture<QString> future = QtConcurrent::run(helloWorldFunction);
...
QList<QString> results = future.results();注: 計算の開始と終了を示すために、QPromise::start() やQPromise::finish() を呼び出す必要はありません (QPromise を使用する場合に通常行うように)。QtConcurrent::run() は、実行開始前と終了後に常にこれらを呼び出します。
実行の一時停止とキャンセル
QPromise API では、必要に応じて計算の一時停止やキャンセルを行うこともできます:
void aFunction(QPromise<int> &promise)
{
for (int i = 0; i < 100; ++i) {
promise.suspendIfRequested();
if (promise.isCanceled())
return;
// computes the next result, may be time consuming like 1 second
const int res = ... ;
promise.addResult(res);
}
}
QFuture<int> future = QtConcurrent::run(aFunction);
... // user pressed a pause button after 10 seconds
future.suspend();
... // user pressed a resume button after 10 seconds
future.resume();
... // user pressed a cancel button after 10 seconds
future.cancel();future.suspend() を呼び出すと、実行中のタスクに対して実行を一時停止するよう要求します。このメソッドを呼び出した後、実行中のタスクは、その反復ループ内で次にpromise.suspendIfRequested() が呼び出された時点で一時停止します。この場合、実行中のタスクはpromise.suspendIfRequested() の呼び出しでブロックされます。ブロックされた呼び出しは、future.resume() が呼び出された後にブロックが解除されます。 なお、suspendIfRequested() は内部的に待機条件を使用してブロックを解除するため、実行中のスレッドは、呼び出し元のスレッドから再開要求が届いたかどうかを定期的に確認するためにブロックされている間、リソースを無駄にすることなくアイドル状態になります。
最後の行でのfuture.cancel() の呼び出しにより、次回のpromise.isCanceled() の呼び出しではtrue が返され、aFunction はそれ以上の結果報告を行わずに即座に終了します。
注: キャンセル後に計算を停止するためにQPromise::finish() を呼び出す必要はありません (QPromise を使用する場合に通常行うような操作です)。QtConcurrent::run() は、実行終了後に常にこれを呼び出します。
進行状況の報告
また、結果の報告とは別に、タスクの進行状況を報告することも可能です。例えば、次のようにします:
voidaFunction(QPromise<int> &promise)
{
promise.setProgressRange(0, 100);
intresult= 0;
for(inti= 0; i< 100;++i) {
// タスクの一部を計算する
const intpart=...;
result+=part;
promise.setProgressValue(i);
}
promise.addResult(result);
}
QFutureWatcher<int>watcher;
QObject::connect(&watcher, &QFutureWatcher::progressValueChanged, [](intprogress){
...;// 進行状況に基づいてGUIを更新する
qDebug() << "current progress:" << progress;
});
watcher.setFuture(QtConcurrent::run(aFunction));呼び出し側は、QtConcurrent::run() によって返された `QFuture ` に対して `QFutureWatcher ` を設定し、その `progressValueChanged() ` シグナルに接続して、例えばグラフィカルユーザーインターフェースを適宜更新します。
オーバーロードされたoperator()() による関数の呼び出し
デフォルトでは、QtConcurrent::run() は「Run With Promise」モードにおいて、operator()() がオーバーロードされたファンクタをサポートしていません。オーバーロードされたファンクタを使用する場合、ユーザーは次のように、QtConcurrent::run() に渡すテンプレートパラメータとして結果型を明示的に指定する必要があります。
© 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.