Sur cette page

Tâche concurrente

QtConcurrent::task fournit une interface alternative pour exécuter une tâche dans un thread distinct. La valeur de retour de la fonction est accessible via l'API QFuture.

Si vous souhaitez simplement exécuter une fonction dans un thread distinct sans modifier aucun paramètre, utilisez QtConcurrent::run, car cela vous permet d’écrire moins de code. La fonction QtConcurrent::task est destinée aux cas où vous devez effectuer des étapes de configuration supplémentaires.

Cette fonction fait partie du Qt Concurrent framework.

Optimisation des inclusions

Si vous incluez l’en-tête <QtConcurrent>, l’intégralité du module Qt Concurrent ainsi que l’intégralité du module Qt Core seront incluses, ce qui peut augmenter les temps de compilation et la taille des binaires. Pour utiliser la fonction QtConcurrent::task(), vous pouvez inclure un en-tête plus spécifique :

#include <QtConcurrentTask>

Interface fluide

La fonction ` QtConcurrent::task ` renvoie une instance d’une classe auxiliaire appelée ` QtConcurrent::QTaskBuilder`. En règle générale, vous n’avez pas besoin de créer manuellement une instance de cette classe. La classe ` QtConcurrent::QTaskBuilder ` fournit une interface permettant d’ajuster différents paramètres de tâches de manière en chaîne. Cette approche est connue sous le nom d’« interface fluide ».

Il vous suffit de définir les paramètres dont vous avez besoin, puis de lancer une tâche. Pour finaliser la configuration d’une tâche, vous devez appeler la fonction ` QtConcurrent::QTaskBuilder::spawn`. Cette fonction est non bloquante (c’est-à-dire qu’elle renvoie immédiatement un objet `Future`), mais il n’est pas garanti que la tâche démarre immédiatement. Vous pouvez utiliser les classes ` QFuture ` et ` QFutureWatcher ` pour surveiller l’état de la tâche.

Vous trouverez ci-dessous d'autres exemples et explications.

Exécution d’une tâche dans un thread distinct

Pour exécuter une fonction dans un autre thread, utilisez QtConcurrent::QTaskBuilder::spawn:

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

Cela exécutera une fonction lambda dans un thread distinct obtenu à partir de l’ QThreadPool par défaut.

Transmission d’arguments à la tâche

Pour appeler une fonction avec des arguments, il suffit de les passer à ` QtConcurrent::QTaskBuilder::withArguments` :

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

Une copie de chaque argument est créée au moment où QtConcurrent::QTaskBuilder::withArguments est appelé, et ces valeurs sont transmises au thread lorsque celui-ci commence à exécuter la tâche. Les modifications apportées aux arguments après l’appel de QtConcurrent::QTaskBuilder::withArguments ne sont pas visibles par le thread.

Si vous souhaitez exécuter une fonction qui accepte des arguments par référence, vous devez utiliser les fonctions auxiliaires std::ref/cref. Ces fonctions créent des wrappers légers autour des arguments transmis :

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

Assurez-vous que tous les objets encapsulés persistent suffisamment longtemps. Un comportement indéfini peut se produire si une tâche survit à l’objet encapsulé par std::ref/cref.

Retour de valeurs depuis la tâche

Vous pouvez obtenir le résultat d’une tâche à l’aide de l’API ` QFuture ` :

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

Notez que ` QFuture::result()` est un appel bloquant : il attend que le résultat soit disponible. Utilisez ` QFutureWatcher ` pour recevoir une notification lorsque la tâche a terminé son exécution et que le résultat est disponible.

Si vous souhaitez transmettre un résultat à une autre tâche asynchrone, vous pouvez utiliser QFuture::then() pour créer une chaîne de tâches dépendantes. Consultez la documentation de QFuture pour plus de détails.

Fonctionnalités supplémentaires de l’API

Utilisation de différents types d’objets appelables

À proprement parler, vous pouvez utiliser n’importe quel type de tâches et d’arguments qui satisfont à la condition suivante :

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

Vous pouvez utiliser une fonction libre :

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

Vous pouvez utiliser une fonction membre :

QString result("Hello, world!");

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

Vous pouvez utiliser un objet appelable doté d'un opérateur () :

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

Si vous souhaitez utiliser un objet appelable existant, vous devez soit le copier/déplacer vers ` QtConcurrent::task `, soit l'envelopper avec `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

Utilisation d'un pool de threads personnalisé

Vous pouvez spécifier un pool de threads personnalisé :

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

Définition de la priorité d’une tâche

Vous pouvez définir la priorité d'une tâche :

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

Si vous n'avez pas besoin d'un objet « future », vous pouvez appeler ` QtConcurrent::QTaskBuilder::spawn` (QtConcurrent::FutureResult::Ignore) :

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

Vous pouvez accéder à l’objet « promise » associé à la tâche en définissant un argument supplémentaire de type « QPromise<T> & » à l’intérieur de la fonction. Cet argument supplémentaire doit être le premier argument passé à la fonction et, comme en mode « Exécution concurrente avec Promise », la fonction doit renvoyer le type « void ». Le rapport des résultats s’effectue via l’API « QPromise » :

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.