Auf dieser Seite

Multithreading-Technologien in Qt

Qt bietet zahlreiche Klassen und Funktionen für die Arbeit mit Threads. Im Folgenden werden vier verschiedene Ansätze vorgestellt, mit denen Qt-Programmierer Multithread-Anwendungen implementieren können.

QThread: Low-Level-API mit optionalen Ereignisschleifen

QThread bildet die Grundlage der gesamten Thread-Steuerung in Qt. Jede ` QThread `-Instanz repräsentiert und steuert einen Thread.

QThread QThread kann entweder direkt instanziiert oder als Unterklasse verwendet werden. Die Instanziierung eines stellt eine parallele Ereignisschleife bereit, wodurch „ “-Slots in einem sekundären Thread aufgerufen werden können. Durch die Erstellung einer Unterklasse von kann die Anwendung den neuen Thread vor dem Start seiner Ereignisschleife initialisieren oder parallelen Code ohne Ereignisschleife ausführen. QObject QThread

Beispiele zur Verwendung von „ QThread “ finden Sie unter „ QThread class reference “ und in den Threading-Beispielen.

QThreadPool und QRunnable: Wiederverwendung von Threads

Das häufige Erstellen und Beenden von Threads kann ressourcenintensiv sein. Um diesen Aufwand zu reduzieren, können vorhandene Threads für neue Aufgaben wiederverwendet werden. „ QThreadPool “ ist eine Sammlung wiederverwendbarer QThreads.

Um Code in einem der Threads von ` QThreadPool` auszuführen, implementieren Sie ` QRunnable::run()` neu und instanziieren Sie die Unterklasse ` QRunnable`. Verwenden Sie ` QThreadPool::start()`, um ` QRunnable ` in die Ausführungswarteschlange von ` QThreadPool` aufzunehmen. Sobald ein Thread verfügbar ist, wird der Code innerhalb von ` QRunnable::run()` in diesem Thread ausgeführt.

Jede Qt-Anwendung verfügt über einen globalen Thread-Pool, auf den über ` QThreadPool::globalInstance()` zugegriffen werden kann. Dieser globale Thread-Pool hält automatisch eine optimale Anzahl von Threads aufrecht, basierend auf der Anzahl der Kerne in der CPU. Es kann jedoch auch ein separater ` QThreadPool ` erstellt und explizit verwaltet werden.

Qt Concurrent: Verwendung einer High-Level-API

Das Qt Concurrent Modul bietet High-Level-Funktionen, die einige gängige Muster paralleler Berechnungen abdecken: „map“, „filter“ und „reduce“. Im Gegensatz zur Verwendung von ` QThread ()` und ` QRunnable` erfordern diese Funktionen niemals den Einsatz von Low-Level-Threading-Primitiven wie Mutexen oder Semaphoren. Stattdessen geben sie ein „ QFuture “-Objekt zurück, mit dem die Ergebnisse der Funktionen abgerufen werden können, sobald diese bereitstehen. Über „ QFuture “ lässt sich zudem der Rechenfortschritt abfragen sowie die Berechnung anhalten, fortsetzen oder abbrechen. Der Einfachheit halber ermöglicht „ QFutureWatcher “ die Interaktion mit „ QFutures“ über Signale und Slots.

Qt ConcurrentDie Algorithmen „map“, „filter“ und „reduce“ verteilen die Berechnung automatisch auf alle verfügbaren Prozessorkerne, sodass heute geschriebene Anwendungen auch dann weiterhin skalierbar sind, wenn sie später auf einem System mit mehr Kernen eingesetzt werden.

Dieses Modul stellt außerdem die Funktion „ QtConcurrent::run()“ bereit, mit der beliebige Funktionen in einem anderen Thread ausgeführt werden können. „ QtConcurrent::run()“ unterstützt jedoch nur einen Teil der Funktionen, die für die „map“--, „filter“- und „reduce“-Funktionen verfügbar sind. Mit ` QFuture ` kann der Rückgabewert der Funktion abgerufen und überprüft werden, ob der Thread läuft. Ein Aufruf von ` QtConcurrent::run()` nutzt jedoch nur einen Thread, kann nicht angehalten, fortgesetzt oder abgebrochen werden und lässt sich nicht auf seinen Fortschritt abfragen.

Weitere Informationen zu den einzelnen Funktionen finden Sie in der Qt Concurrent Moduldokumentation für Details zu den einzelnen Funktionen.

WorkerScript: Threading in QML

Der QML-Typ „ WorkerScript “ ermöglicht es, JavaScript-Code parallel zum GUI-Thread auszuführen.

Jeder „ WorkerScript “-Instanz kann ein „ .js “-Skript zugeordnet werden. Wenn „ WorkerScript.sendMessage()“ aufgerufen wird, wird das Skript in einem separaten Thread (und einem separaten „ QML context “) ausgeführt. Wenn die Ausführung des Skripts beendet ist, kann es eine Antwort an den GUI-Thread zurücksenden, wodurch der Signal-Handler „ WorkerScript.onMessage()“ aufgerufen wird.

Die Verwendung eines „ WorkerScript “ ähnelt der Verwendung eines „worker QObject “, der in einen anderen Thread verschoben wurde. Die Datenübertragung zwischen den Threads erfolgt über Signale.

Weitere Informationen zur Implementierung des Skripts sowie eine Liste der Datentypen, die zwischen Threads übergeben werden können, finden Sie in der Dokumentation zu „ WorkerScript “.

Auswahl eines geeigneten Ansatzes

Wie oben gezeigt, bietet Qt verschiedene Lösungen für die Entwicklung von Anwendungen mit Threads. Die richtige Lösung für eine bestimmte Anwendung hängt vom Zweck des neuen Threads und dessen Lebensdauer ab. Im Folgenden finden Sie einen Vergleich der Threading-Technologien von Qt, gefolgt von empfohlenen Lösungen für einige Beispielanwendungsfälle.

Vergleich der Lösungen

FunktionQThreadQRunnable und QThreadPoolQtConcurrent::run()Qt Concurrent (Map, Filter, Reduce)WorkerScript
SpracheC++C++C++C++QML
Die Thread-Priorität kann festgelegt werdenJaJa
Ein Thread kann eine Ereignisschleife ausführenJa
Ein Thread kann Datenaktualisierungen über Signale empfangenJa (Empfang über einen Worker- QObject)Ja (Empfang über WorkerScript)
Ein Thread kann mithilfe von Signalen gesteuert werdenJa (Empfang über QThread)Ja (Empfang über QFutureWatcher)
Der Thread kann über ein QFutureTeilweiseJa
Integrierte Funktion zum Anhalten/Fortsetzen/AbbrechenJa

Beispiel-Anwendungsfälle

Laufzeit des ThreadsVorgangLösung
Ein AufrufFühren Sie eine neue lineare Funktion in einem anderen Thread aus, optional mit Fortschrittsmeldungen während der Ausführung.Qt bietet verschiedene Lösungen:
Ein AufrufFühren Sie eine vorhandene Funktion in einem anderen Thread aus und rufen Sie deren Rückgabewert ab.Führen Sie die Funktion mit ` QtConcurrent::run()` aus. Lassen Sie ein ` QFutureWatcher ` das Signal ` finished()` ausgeben, sobald die Funktion zurückgekehrt ist, und rufen Sie ` QFutureWatcher::result()` auf, um den Rückgabewert der Funktion abzurufen.
Ein AufrufFühren Sie eine Operation auf allen Elementen eines Containers durch und nutzen Sie dabei alle verfügbaren Kerne. Beispielsweise die Erstellung von Miniaturansichten aus einer Liste von Bildern.Verwenden Sie die Funktion „ QtConcurrent::filter()“ von „ Qt Concurrent “, um Containerelemente auszuwählen, und die Funktion „ QtConcurrent::map()“, um eine Operation auf jedes Element anzuwenden. Um die Ausgabe zu einem einzigen Ergebnis zusammenzufassen, verwenden Sie stattdessen „ QtConcurrent::filteredReduced()“ und „ QtConcurrent::mappedReduced()“.
Ein Aufruf/PermanentFühren Sie eine langwierige Berechnung in einer reinen QML-Anwendung durch und aktualisieren Sie die Benutzeroberfläche, sobald die Ergebnisse vorliegen.Platzieren Sie den Berechnungscode in einem „ .js “-Skript und fügen Sie es einer „ WorkerScript “-Instanz hinzu. Rufen Sie ` WorkerScript.sendMessage()` auf, um die Berechnung in einem neuen Thread zu starten. Lassen Sie das Skript auch `sendMessage()` aufrufen, um das Ergebnis an den GUI-Thread zurückzugeben. Verarbeiten Sie das Ergebnis in ` onMessage ` und aktualisieren Sie dort die Benutzeroberfläche.
PermanentLassen Sie ein Objekt in einem anderen Thread laufen, das auf Anfrage verschiedene Aufgaben ausführen und/oder neue Daten zur Verarbeitung empfangen kann.Erstellen Sie eine Unterklasse von ` QObject `, um einen Worker zu erstellen. Instanziieren Sie dieses Worker-Objekt und ein ` QThread`. Verschieben Sie den Worker in den neuen Thread. Senden Sie Befehle oder Daten über Queued-Signal-Slot-Verbindungen an das Worker-Objekt.
PermanentFühren Sie eine rechenintensive Operation wiederholt in einem anderen Thread aus, wobei der Thread keine Signale oder Ereignisse empfangen muss.Schreiben Sie die Endlosschleife direkt in eine Neuimplementierung von ` QThread::run()` ein. Starten Sie den Thread ohne Ereignisschleife. Lassen Sie den Thread Signale ausgeben, um Daten an den GUI-Thread zurückzusenden.

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