IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Multithreading Discussion :

Architecture multithread [QThread]


Sujet :

Multithreading

  1. #1
    Invité
    Invité(e)
    Par défaut Architecture multithread
    Bonjour,

    Je développe actuellement une application et je bloque sur l'architecture à adopter pour la faire tourner en multi-thread.

    Mon besoin consiste à faire tourner un premier thread servant à communiquer avec un appareil de mesure, puis à envoyer les résultats à second thread chargé de traiter ces données pendant que le premier thread exécute le cycle de mesures suivant. Ces deux thread son membre d'une classe Manager chargée d'assurer leur création et la communication avec l'IHM. Cette classe doit également récupérer les données traitées et le rediriger vers les modules idoines (IHM pour affichage et/ou modèle pour persistence).

    J'ai lu et relu FAQ, Doc et tutos sans parvenir à faire émerger une solution pertinente.

    La solution consistant à utiliser un moveToThread() vers un objet QThread ne me semble pas plus pertinente que celle consistant à hériter directement QThread et dans les deux, j'aurais de sérieuses difficultés à faire communiquer ou fonctionner les différents parties de mon application comme je l'entend.

    Mes yeux me piquent à force de lire et relire des articles et forums qui commencent à se répéter, je m'en remet donc à vous.

  2. #2
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Salut,
    Citation Envoyé par Lelfic Voir le message
    La solution consistant à utiliser un moveToThread() vers un objet QThread ne me semble pas plus pertinente que celle consistant à hériter directement QThread et dans les deux, j'aurais de sérieuses difficultés à faire communiquer ou fonctionner les différents parties de mon application comme je l'entend
    La différence se situe sur l’exécution des slots de ton objet. Pour qu'un slot s'éxécute dans un thread il faut que le thread lance l'eventlloop et un QThread ne doit pas être associé au thread qu'il interface. C'est pour cela que faire un QObject et l'associé à un QThread est intéressant.

    Pour la communication et le fonctionnement de tes différentes parties, faudrait que tu explique plus.

  3. #3
    Invité
    Invité(e)
    Par défaut
    Mon thread numéro 1 doit utiliser une procédure précise qui se répète indéfiniment, ma première idée était donc un while dans le run() du thread. Le problème ici est qu'il pas d'eventloop, or, pour envoyer les résultats au thread n°2 à chaque itération, il faut des signaux et slots (d'après mes lectures, c'est le seul moyen de faire communiquer des threads entre eux). Donc ce n'est pas viable.

    La seconde solution, un QObject envoyé à un thread, règle ce problème;

    Mais cela me pause un tout autre problème.
    - Premièrement, cette procédure nécessite de mettre le thread en pause à certains endroits, ce qui n'est plus possible puisque l'objet, dans ce cas, n'hérite pas de QThread et la fonction sleep est protected (bien que la doc la prétende publique).

    De plus, je suis peu familier du multi-threading, et je suis encore en train de réfléchir, laborieusement, à la façon de faire se répéter inlassablement la procédure sus-mentionnée. Manifestement, je ne sais pas raisonner en multi-threading, et je me demande où je dois placer ce while dans la deuxième solution.

  4. #4
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Citation Envoyé par Lelfic Voir le message
    Mon thread numéro 1 doit utiliser une procédure précise qui se répète indéfiniment, ma première idée était donc un while dans le run() du thread. Le problème ici est qu'il pas d'eventloop, or, pour envoyer les résultats au thread n°2 à chaque itération, il faut des signaux et slots (d'après mes lectures, c'est le seul moyen de faire communiquer des threads entre eux). Donc ce n'est pas viable.
    Il te faut l'eventloop uniquement pour l'execution du slot pas pour l'envoie du signal. DOnc ton thread 1 n'en as pas besoin s'il ne fait qu’émettre des signaux.

    La seconde solution, un QObject envoyé à un thread, règle ce problème;

    ...
    J'ai pas trop compris ton explication....

  5. #5
    Invité
    Invité(e)
    Par défaut
    En somme :

    Thread n°1 :

    Ce thread exécute une procédure qui prend du temps. Pour le faire sans bloquer l'IHM, il me faut l'exécuter dans un thread autre que le thread principal. Et pour recevoir les ordres venant du thread principal (commence, arrête, etc), j'ai besoin des slots, il me faut donc un eventloop.

    Donc, la solution que j'ai adopté consiste à créer simplement cet objet en faisant de ses fonctions des slots. L'un des membres de cet objet est un QThread. J'utilise sur mon objet la fonction moveToThread afin de faire exécuter ses slots dans le contexte du QThread créé (différent du thread principal).

    Sauf qu'au cours de cette procédure, j'ai besoin de faire des pause, et je ne peux pas utiliser la fonction sleep de QThread depuis mon objet car elle est protected et ne peut être utilisée que par un objet héritant de QThread. Sur ce point j'ai opté pour la seule solution à laquelle j'ai pensé : j'ai utilisé, en lieu et place du QThread, un objet dérivant QThread et dont la seule différence avec son parent consiste à rendre publique la fonction sleep;

    Thread n°2 :

    Ce Thread est en charge de traiter les données récoltées par le thread n°1 pendant que ce dernier effectue le cycle suivant de sa procédure. Ce traitement peut prendre plusieurs secondes selon l'ampleur des données reçues, et ne doit pas bloquer ni l'IHM ni le thread n°1. Il me faut donc un troisième contexte de thread.

    J'ai opté ici pour la même architecture que le Thread n°1. Reste à les synchroniser.

    Voilà, j'espère que c'est plus clair. J'ai la tête là-dedans depuis des semaines et j'ai donc un peu de mal à m'expliquer clairement pour qui ne connait rien du projet.

    Cette architecture vous semble-t-elle correcte ? Réaliste ? Complètement aberrante ?

  6. #6
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Pourquoi le sleep?

  7. #7
    Invité
    Invité(e)
    Par défaut
    Parce que je n'ai pas trouvé d'autre moyen de faire faire une pause à ma procédure (une boucle while utiliserait 100% du processeur inutilement).

  8. #8
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Ok.
    Une proposition.
    Tu créé un QObject avec des signaux et des slots.

    Au lieu de faire un while, tu va utiliser un QTimer. Par exemple la méthode static :
    http://qt-project.org/doc/qt-4.8/qtimer.html#singleShot

    Le contenue de ta bloucle est un slot connecté au timer

    Tu associe ce QObject a un QThread pour que ses slot s’exécute dans le thread.

    J'ai commencé (mais pas fini...) un tuto ici : http://yan-verdavaine.developpez.com...er_l_eventloop

    Ne fait pas attention au fautes...

  9. #9
    Invité
    Invité(e)
    Par défaut
    J'ai fini par trouver une solution qui semble fonctionner.

    Je ne comprends pas bien l'utilisation d'un QTimer, dans la mesure où dans mon cas, ce n'est pas le temps qui entre en compte, les thread doivent se synchroniser entre eux sans horloge absolue.

    Mais ta réponse m'a quand même permit de trouver une solution : j'utilise des signaux et slots pour communiquer les débuts et fin de procédure.

    Mon manager central lance les deux procédure puis ce place en état d'attente. Chacune de ces procédures envoie un signal au manager lorsqu'elle a terminé et le manager ne relance les procédure que lorsque qu'il a reçu les deux signaux.

    L'idée est simple, mais l'implémentation semble lourde au premier abord (peut-être à cause du pattern Etat donné au manager). Cependant, je pense qu'avec la croissance de l'application, ce sera sur la durée la méthode la plus économique.

    Merci beaucoup pour ton aide.
    Dernière modification par Invité ; 14/08/2012 à 15h47.

  10. #10
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    La QTimer tu le mets à zero et il execute au plus vite ta fonction.
    Le but est uniquement de déporté ta boucle dans l'eventloop du thread.

    Tu peux aussi utiliser startTimer(0) et en reimplementant QObject::timerEvent(QTimerEvent*).

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 8
    Dernier message: 10/07/2008, 09h16
  2. architecture serveur multithread
    Par hisoka dans le forum Développement
    Réponses: 2
    Dernier message: 25/11/2006, 21h05
  3. [Architecture] Interface entre C++ & Java
    Par yanis97 dans le forum Entrée/Sortie
    Réponses: 13
    Dernier message: 13/07/2004, 15h46
  4. Multithreading sous HP Ux 11
    Par pykoon dans le forum Autres éditeurs
    Réponses: 1
    Dernier message: 18/10/2002, 23h36
  5. architecture
    Par pons dans le forum CORBA
    Réponses: 3
    Dernier message: 11/06/2002, 11h10

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo