2011-11-19 4 views
1

Donc, si je comprends bien, si j'ai une classe FunctionsClass qui hérite QObject et je mets cette classe sur un QThread appelé FunctionClassThread en faisant:Confusion utilisant des fils Qt

FunctionsClass classObj; 
classObj.moveToThread(&FunctionClassThread); 
FunctionClassThread.start(); 

D'après ce que je comprends cette méthode de la configuration d'un thread ne gère que l'exécution des slots dans le FunctionsClass, ce qui signifie que le thread FunctionsClass peut être bloqué si un slot dans FunctionsClass a une boucle infinie pour une raison quelconque. Donc, mes questions sont: Comment puis-je exécuter les fonctions de FunctionsClass sur un thread pas seulement les fentes? Y at-il un moyen de placer un objet entier (fonctions, variables membres, etc) sur un thread pour l'exécution de code/données de cet objet entier seulement? Et est-ce que ma compréhension de la façon dont le thread va gérer l'exécution des slots est correcte?

Répondre

1

Lorsque vous exécutez une méthode d'un objet, elle est exécutée dans le thread que vous appelez la méthode. Peu importe où le QObject vit. Si vous voulez invoquer une méthode pour qu'elle soit exécutée de manière asynchrone dans un autre thread, vous devrez gérer la situation de façon à ce que le message soit affiché, attende que le thread soit disponible (il peut être occupé, il doit retournez le contrôle à la boucle d'événement d'abord) puis exécutez la méthode.

Cela peut être fait en utilisant des signaux et des emplacements, avec la connexion habituelle. Si vous ne souhaitez pas utiliser ce mécanisme, vous pouvez utiliser QMetaObject, mais vous devez toujours déclarer ces emplacements comme des emplacements. La méthode statique invokeMethod, si appelée avec Qt :: QueuedConnection invoquera la méthode dans le thread dans lequel l'objet possédant la méthode est vivant. Vous pouvez également passer des arguments à la méthode et en renvoyer des valeurs.

Considérer que tous les types de données que vous voulez pouvoir passer d'un fil à un autre doivent être enregistrés avec qRegisterMetaType et doivent respecter les conditions indiquées dans ce document.

0

Les méthodes d'une classe s'exécuteront dans le contexte du thread qui les appelle. Si vous déplacez une classe QObject vers un thread (appelons-la thread de travail), seules les méthodes de cette classe appelées directement (ou indirectement) à partir de la méthode run() du thread de travail s'exécuteront dans le contexte du worker fil. Si vous souhaitez appeler des méthodes de cette classe à partir d'un autre thread, mais les exécuter dans le contexte du thread de travail, vous devez obtenir un message pour le thread de travail afin qu'il puisse appeler la méthode tu veux. C'est essentiellement ce qui est réalisé par les signaux Qt et les slots lorsque les limites des fils sont franchies.

Avec beaucoup de travail supplémentaire, il y a deux autres façons de faire la même chose. Premièrement, QThread s ont une boucle d'événement qui est démarrée par défaut si vous ne surchargez pas run(). Vous pouvez créer custom events que vous pouvez publier dans la boucle d'événements, ce qui peut déclencher une activité dans votre classe qui s'exécutera dans le contexte du thread de travail. La seconde méthode consiste à appeler les méthodes de votre classe à partir d'un autre thread qui modifie les champs de classe surveillés par le thread de travail. Vous devez être sûr que l'accès à l'un de ces champs est synchronisé avec un mécanisme tel qu'un mutex.