このページでは

Qtにおけるマルチスレッド技術

Qt には、スレッドを扱うための多くのクラスや関数が用意されています。以下に、Qt プログラマーがマルチスレッドアプリケーションを実装するために利用できる 4 つの異なるアプローチを紹介します。

QThread:オプションのイベントループを備えた低レベルAPI

QThread は、Qtにおけるすべてのスレッド制御の基盤となります。各QThread インスタンスは、1つのスレッドを表し、制御します。

QThread QThread は、直接インスタンス化することも、サブクラス化することもできます。 をインスタンス化すると、並列イベントループが提供され、 のスロットをセカンダリスレッドで呼び出すことが可能になります。 をサブクラス化することで、アプリケーションはイベントループを開始する前に新しいスレッドを初期化したり、イベントループを使用せずに並列コードを実行したりすることができます。QObject QThread

`QThread` の使用方法については、QThread class reference およびスレッド処理のサンプルを参照してください。

QThreadPool と QRunnable:スレッドの再利用

スレッドの頻繁な作成と破棄は、オーバーヘッドが大きくなる可能性があります。このオーバーヘッドを軽減するために、既存のスレッドを新しいタスクに再利用することができます。QThreadPool は、再利用可能なQThreadの集合体です。

QThreadPool のスレッドのいずれかでコードを実行するには、QRunnable::run()を再実装し、サブクラス化されたQRunnable をインスタンス化します。QThreadPool::start()を使用して、QRunnable をQThreadPool の実行キューに追加します。スレッドが利用可能になると、QRunnable::run()内のコードがそのスレッドで実行されます。

各Qtアプリケーションにはグローバルスレッドプールがあり、QThreadPool::globalInstance()を通じてアクセスできます。このグローバルスレッドプールは、CPUのコア数に基づいて最適なスレッド数を自動的に維持します。ただし、個別のQThreadPool を作成して明示的に管理することも可能です。

Qt Concurrent: 高レベルAPIの使用

この Qt Concurrent モジュールは、map、filter、reduceといった一般的な並列計算パターンを扱う高レベル関数を提供します。QThread やQRunnable を使用する場合とは異なり、これらの関数では、ミューテックスやセマフォといった低レベルのスレッドプリミティブを使用する必要は一切ありません。 その代わりに、これらの関数はQFuture オブジェクトを返すため、計算結果が準備でき次第、このオブジェクトを使用して結果を取得できます。また、QFuture を使用することで、計算の進捗状況を照会したり、計算を一時停止・再開・中止したりすることも可能です。利便性を高めるため、QFutureWatcher では、シグナルとスロットを介してQFutureとの連携が可能になっています。

Qt Concurrentの map、filter、reduce アルゴリズムは、利用可能なすべてのプロセッサコアに計算を自動的に分散させるため、今日作成されたアプリケーションは、将来より多くのコアを持つシステムに展開された際も、引き続きスケーラビリティを維持できます。

また、このモジュールは、任意の関数を別のスレッドで実行できる `QtConcurrent::run()` 関数も提供しています。ただし、`QtConcurrent::run()` は、`map`、`filter`、`reduce` 関数で利用可能な機能の一部のみをサポートしています。QFuture を使用すると、関数の戻り値を取得したり、スレッドが実行中かどうかを確認したりできます。ただし、QtConcurrent::run()の呼び出しは1つのスレッドのみを使用し、一時停止・再開・キャンセルはできず、進行状況の照会もできません。

個々の関数の詳細については、 Qt Concurrent モジュールのドキュメントを参照してください。

WorkerScript: QML でのスレッド処理

WorkerScript QML タイプを使用すると、JavaScript コードを GUI スレッドと並行して実行できます。

各WorkerScript インスタンスには、1 つの.js スクリプトを関連付けることができます。WorkerScript.sendMessage() が呼び出されると、スクリプトは別のスレッド(および別のQML context )で実行されます。スクリプトの実行が終了すると、GUI スレッドに返信を送信することができ、それによってWorkerScript.onMessage() シグナルハンドラが呼び出されます。

WorkerScript の使用方法は、別のスレッドに移動されたワーカーQObject を使用する場合と似ています。スレッド間のデータ転送はシグナルを介して行われます。

スクリプトの実装方法や、スレッド間で受け渡し可能なデータ型のリストについては、『WorkerScript 』のドキュメントを参照してください。

適切なアプローチの選択

上述のように、Qt ではスレッド化されたアプリケーションを開発するためのさまざまなソリューションが提供されています。特定のアプリケーションに適したソリューションは、新しいスレッドの目的とスレッドの存続期間によって異なります。以下に、Qt のスレッド技術の比較を示し、その後にいくつかのユースケース例に対する推奨ソリューションを記載します。

ソリューションの比較

機能QThreadQRunnable およびQThreadPoolQtConcurrent::run()Qt Concurrent (Map、Filter、Reduce)WorkerScript
言語C++C++C++C++QML
スレッドの優先度を指定できますはいはい
スレッドはイベントループを実行できるはい
スレッドはシグナルを通じてデータの更新を受け取ることができるはい(ワーカーQObject によって受信されます)はい(WorkerScript が受信)
スレッドはシグナルを使用して制御できますはい(QThread によって受信)はい(QFutureWatcher によって受信)
スレッドはQFuture一部はい
一時停止・再開・キャンセルの機能が標準で搭載されているはい

使用例

スレッドの存続期間操作ソリューション
1回の呼び出し別のスレッド内で新しい線形関数を実行し、必要に応じて実行中の進捗状況を更新する。Qt では、以下の解決策が提供されています:
1回の呼び出し別のスレッド内で既存の関数を実行し、その戻り値を取得します。QtConcurrent::run() を使用して関数を実行します。関数が戻ったときに、QFutureWatcher がfinished() シグナルを発信するようにし、QFutureWatcher::result() を呼び出して関数の戻り値を取得します。
1回の呼び出し利用可能なすべてのコアを使用して、コンテナ内のすべての項目に対して操作を実行します。たとえば、画像のリストからサムネイルを生成する場合などです。Qt Concurrent のQtConcurrent::filter()関数を使用してコンテナの要素を選択し、QtConcurrent::map()関数を使用して各要素に操作を適用します。出力を単一の結果に折りたたむには、代わりにQtConcurrent::filteredReduced()およびQtConcurrent::mappedReduced()を使用します。
1回の呼び出し/永続的純粋な QML アプリケーション内で長時間の計算を実行し、結果が準備できたら GUI を更新します。計算コードを.js スクリプトに記述し、WorkerScript インスタンスにアタッチします。WorkerScript.sendMessage()を呼び出して、新しいスレッドで計算を開始します。また、スクリプト内でsendMessage()を呼び出し、結果をGUIスレッドに返します。onMessage 内で結果を処理し、そこでGUIを更新します。
永続的別のスレッドに存在し、要求に応じてさまざまなタスクを実行したり、処理対象となる新しいデータを受け取ったりできるオブジェクトを用意します。QObject をサブクラス化してワーカーを作成します。このワーカーオブジェクトとQThread をインスタンス化します。ワーカーを新しいスレッドに移動させます。キュー化されたシグナル・スロット接続を介して、ワーカーオブジェクトにコマンドやデータを送信します。
永続的別のスレッドで、信号やイベントを受信する必要のない、負荷の高い操作を繰り返し実行します。QThread::run() の再実装内で、無限ループを直接記述します。イベントループなしでスレッドを起動します。スレッドからシグナルを発行して、GUI スレッドにデータを返送させます。

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