web-dev-qa-db-fra.com

moveToThread vs dérivant de QThread dans Qt

Quand devrait-on préférer moveToThread au sous-classement QThread?

Ce lien montre que les deux méthodes fonctionnent. Sur quelle base devrais-je décider quoi utiliser de ces deux?

20
Aquarius_Girl

Comme point de départ: n'utilisez ni l'un ni l'autre. Dans la plupart des cas, vous souhaitez exécuter une unité de travail de manière asynchrone. Utilisez QtConcurrent::run pour cela.

Si vous avez un objet qui réagit à des événements et/ou utilise des minuteries, il s'agit d'une QObject qui devrait être non bloquante et faire partie d'un fil, éventuellement partagé avec d'autres objets.

Un tel objet peut également encapsuler des API bloquantes.

Le sous-classement QThread n'est jamais nécessaire en pratique. C'est comme un sous-classement QFile. QThread est un handle de thread. Il enveloppe une ressource système. Surcharger c'est un peu bête.

7
Kuba Ober

QThread est une abstraction de threads de bas niveau. Regardez d'abord les API de haut niveau QtConcurrent module et QRunnable

Si rien de tout cela ne vous convient, lisez cet ancien article , il indique comment utiliser QThread. Pensez au fil et à la tâche effectués dans ce fil en tant qu'objets séparés, ne les mélangez pas.

Ainsi, si vous devez écrire un wrapper de thread personnalisé, spécifique ou étendu, vous devez sous-classer QThread.

Si vous avez une classe dérivée QObject avec des signaux et des slots, utilisez moveToThread dessus.

Dans d'autres cas, utilisez QtConcurrent, QRunnable et QThreadPoll.

3
Jeka

La réponse simple est TOUJOURS . Lorsque vous déplacez un objet dans le fil:

  • il est facile d'écrire un test de code
  • il est facile de refactoriser le code (vous pouvez utiliser le thread mais ce n’est pas obligatoire).
  • vous ne mélangez pas la fonctionnalité de thread avec la logique métier
  • il n'y a pas de problème avec la durée de vie de l'objet

Lorsque vous sous-classe QThread

  • il est plus difficile d'écrire le test
  • le processus de nettoyage d’objet peut devenir très déroutant et conduire à d’étranges erreurs.

Vous trouverez une description complète du problème sur le blog Qt: Vous le faites mal… .

QtConcurrent::run est également très pratique.

Rappelez-vous que par défaut, les machines à sous tentent de basculer entre les marches lorsque le signal envoyé depuis un autre objet de fil est attribué. Pour plus de détails, voir la documentation de Qt :: ConnectionType .

0
Marek R