Qt : pourquoi et quand utiliser les threads ?

De la bonne utilisation de la run-loop

La run-loop est un thread. Ou plutôt, chaque instance de la classe QThread possède une run-loop, c’est-à-dire une boucle infinie qui dépile des appels de fonctions à exécuter séquentiellement.

Les premières lignes de code d’une application Qt sont généralement les suivantes :

Ces lignes vous indiquent que vous démarrez toujours une run-loop pour votre application, une seule. Elle a pour rôle de traiter les événements de l’interface graphique ainsi que les signaux que vous émettez.

Avec tout ce que j’ai dit plus haut il apparait évident que chacun de ces appels est bloquant. A ce titre il doit être le plus court possible, si possible en dessous de 100 ms pour être quasi imperceptible aux yeux de l’utilisateur.

Le blocage le plus typique vient du parcours d’une liste. Si vous utilisez une boucle for, vous êtes certain de bloquer le thread pendant la durée du parcours de la liste. Si la tâche à accomplir pour chaque itération dure 100 ms et qu’il y a 100 éléments dans la liste, le parcours durera 10 secondes. L’interface graphique sera donc bloquée pendant 10 secondes, ce qui est inacceptable.

En tout état de cause, même en admettant que le traitement ne soit que de 10 ms, si votre liste contenait tout à coup plusieurs millions d’éléments, le problème serait le même… et sa solution resterait conceptuelle.

Cet article vous présente un moyen d’éviter ce blocage en toutes circonstances, en effectuant un appel asynchrone à chaque itération dans la liste. Vous ne bloquerez ainsi votre run-loop, et donc l’interface graphique que pendant 100 ms à chaque itération.

Ce principe pourra être appliqué à tout processus bloquant trop longtemps la run-loop.

Une autre erreur très souvent rencontrée est l’utilisation de la fonction sleep() ou QThread::msleep() pour faire une pause dans l’exécution d’un programme. Je traiterai ce problème dans un autre article mais comprenez bien que l’appel de cette fonction interrompt l’exécution de la run-loop de l’objet dans lequel ces fonctions sont appelées pendant le délai indiqué.

La bonne utilisation de la run-loop nécessite de bien connaître l’architecture de son application, et donc de l’avoir définie au préalable. Je traiterai spécifiquement de la question de l’affinité de thread dans un prochain article. Cela dit, lorsque vous émettez un signal ou faites un appel de fonction asynchrone, vous devez toujours savoir quelle l’affinité de thread des objets concernés (l’émetteur et le récepteur).

Bien utiliser la run-loop, avec un unique thread est le meilleur moyen d’offrir une expérience d’utilisation excellente à vos clients tout en utilisant le processeur de manière optimale. Contrairement aux cas exposés plus haut, vous laissez la possibilité au système de gérer efficacement les processus et de les dispatcher sur les coeurs de manière harmonieuse.

Ont-ils le même thread ? Auquel cas il y a de grandes chances pour que l’émission du signal aboutisse à un appel direct au slot. S’ils sont dans des threads différents, dans quel thread la fonction va-t-elle s’exécuter ? Et si vous forcez un passage par la run-loop en utilisant le comportement Qt::QueuedConnection ?

Bref, cela vous ramènera toujours à la question la plus importante : combien de temps mon processus met à s’exécuter ?

Partagez cet article !

Abonnez-vous à notre newsletter !

Si vous souhaitez être notifié lorsqu'un nouvel article est publié, abonnez-vous à notre newsletter et vous recevrez un email dès qu'un article sera publié.

Pages : 1 2 3 4 5

Articles similaires

Qt : l’influence du... Observations Voici la liste de mes principales observations, sans interprétation : Sous Windows, en version Release, une application compilée sous MSVC en 64 bits est environ 50%
Qt : comment implanter un... L’application Voici à présent le fichier main.cpp [crayon-5d83b84ea5978151424900/] Après avoir déclaré une instance de QCoreApplication, nous démarrons le contrôleur et exécutons le traitement threadé. Au bout de
Apprendre à développer ... Une de mes activités est la formation professionnelle à la conception et à la programmation d’applications avec Qt. J’envisage aujourd’hui de créer un MOOC payant pour partager
Qt : Traiter une liste de... Pour qu’une interface graphique reste fluide aux yeux de l’utilisateur, le thread qui la gère ne doit jamais être interrompu plus d’une poignée de millisecondes. Or le
Qt : pourquoi et quand ut... De la bonne utilisation de la run-loop La run-loop est un thread. Ou plutôt, chaque instance de la classe QThread possède une run-loop, c’est-à-dire une boucle infinie
Adopter les flux tirés d... Nous abordons un des points essentiels de l’architecture réseau et applicative efficace et économe : les flux tirés. Partagez cet article ! Abonnez-vous à notre newsletter !
Qt : distribuer ses appli... La distribution d’une application est une étape importante de la vie d’une application, elle nécessite d’être pensée très tôt dans la conception. Cette série d’articles présente les
Utiliser la technique du ... Le lazy-loading, ou chargement paresseux en français, est une réponse simple à la question simple “pourquoi charger plus de données que nous ne pouvons en afficher ?”.
Livre Maîtrisez Qt 5 ... La seconde édition du livre de Tristan Israël, Maîtrisez Qt 5 – Développement d’applications professionnelles, est parue. Vous pouvez le découvrir sur le site des éditions ENI.

Laisser une réponse

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *