Maison > développement back-end > C++ > Comment exécuter des foncteurs ou des Lambdas dans un thread Qt spécifique, similaire à GCD ?

Comment exécuter des foncteurs ou des Lambdas dans un thread Qt spécifique, similaire à GCD ?

DDD
Libérer: 2024-12-16 18:35:12
original
132 Les gens l'ont consulté

How to Execute Functors or Lambdas in a Specific Qt Thread, Similar to GCD?

Comment exécuter un foncteur ou un Lambda dans un thread donné dans Qt, style GCD ?

Problème :

Dans Qt, vous souhaitez exécuter un lambda ou un foncteur dans n'importe quel thread doté d'une boucle d'événement, similaire à la répartition de GCD files d'attente en Objective-C.

Solution :

La solution se concentre sur la fourniture d'un événement qui enveloppe le foncteur vers un objet consommateur résidant dans le thread souhaité. Cette opération est appelée publication de métaappels, et elle peut être implémentée de plusieurs manières.

Qt 5.10 & Up TL;DR :

Vous pouvez appeler des méthodes sur QObjects ou QThreads directement :

// Invoke on the main thread
QMetaObject::invokeMethod(qApp, []{ ... });

// Invoke on an object's thread
QMetaObject::invokeMethod(obj, []{ ... });

// Invoke on a particular thread
QMetaObject::invokeMethod(
    QAbstractEventDispatcher::instance(thread),
    []{ ... });
Copier après la connexion

TL;DR pour les foncteurs :

Plusieurs fonctions de modèle sont fournies pour envelopper le foncteur dans un objet d'événement approprié, ce qui rend la publication de méta-appels pratique.

// Post to the main thread sync
void execInMainThread_sync(std::function<void(void)> func) {
    if(qApp->thread() == QThread::currentThread())
        func();
    else {
        ((App*) qApp)->invokeGenericExec(func, Qt::BlockingQueuedConnection);
    }
}

// Post to the main thread async
void execInMainThread_async(std::function<void(void)> func) {
    ((App*) qApp)->invokeGenericExec(func, Qt::QueuedConnection);
}
Copier après la connexion

TL;DR pour Méthodes/Slots :

Pour les méthodes ou les slots, une macro est définie pour gérer la publication du métacall.

#define POST_METHOD(obj, method) \
    QObject src; \
    QObject::connect(&src, &QObject::destroyed, obj, method, \
                       Qt::QueuedConnection);
Copier après la connexion

Code commun :

Le code fourni comprend des fonctions d'assistance et des macros courantes qui résument l'implémentation de la publication des métaappels pour une utilisation dans différents scénarios.

Exemple :

void test1() {
    QThread t;
    QObject o;
    o.moveToThread(&t);

    // Execute in given object's thread
    postToObject([&]{ o.setObjectName("hello"); }, &o);
    // or
    postToObject(std::bind(&QObject::setObjectName, &o, "hello"), &o);

    // Execute in given thread
    postToThread([]{ qDebug() << "hello from worker thread"; });

    // Execute in the main thread
    postToThread([]{ qDebug() << "hello from main thread"; });
}
Copier après la connexion

Remarque supplémentaire :

Si votre fil de discussion cible n'a pas de boucle d'événement , tel qu'un thread de travail, vous aurez peut-être besoin d'un mécanisme pour démarrer la boucle d'événements au sein du thread. Par exemple, si vous utilisez un minuteur à prise unique pour la publication d'un méta-appel, vous pouvez démarrer la boucle d'événements à l'aide de QThread::exec().

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal