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
DDDoriginal
2024-12-16 18:35:12134parcourir

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),
    []{ ... });

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);
}

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);

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"; });
}

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!

Déclaration:
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