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 :

Mélange de threads Boost et d'une IHM Qt


Sujet :

Multithreading

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 3
    Points : 2
    Points
    2
    Par défaut Mélange de threads Boost et d'une IHM Qt
    Bonjour

    Je code un logiciel avec Qt, sous Visual c++ 2010. Je dois mettre en place des calculs en parallèles, et j'utilise Boost::thread avec un thread_group (je veux éviter si possible de passer par QtConcurrent). Or, à la fin de chaque thread, je veux réactualiser une barre d'avancement Qt (QProgressBar). Comment brancher la fin d'un thread unitaire de Boost sur une réactualisation graphique d'IHM Qt ? Il faudrait peut-être envoyer un signal Qt à la fin du thread pour revenir dans le thread principal, et donc faire hériter ma classe de calcul (foncteur) de QObject ?

    Merci pour vos conseils, je suis un peu bloqué là, même si au pire je repasse tout en Qt.

  2. #2
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut,
    Faudrait vérifier si la signalisation Qt est compatible avec le mutlithreading 'extérieur'.
    Boost.Signal2 peut-il faire l'affaire ?

    Pour des calculs //, plutôt que des threads 'old-style', pourquoi ne pas prendre des bibliothèques dédiées types OpenMP ou Intel TBB

  3. #3
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    Bonjour

    Pour la connexion entre les signaux de boost et de Qt, il y a un tutoriel sur le sujet (de 2008 mais ça ne devrait pas avoir changé depuis) : http://irmatden.developpez.com/tutor...boost-signals/

    Je pense que le problème est que les connexions boost-Qt sont uniquement de type Qt:: DirectConnection (le slot est appelé directement). Or, pour le multithreading, Qt passe par la boucle d'events du thread cible (le thread principal pour l'IHM) pour la connexion signal-slot en faisant des connexions de type Qt::QueuedConnection. Donc je déconseille de passer par boost signal ici.

    Les alternatives :
    - créer un event spécifique pour la mise à jour de la barre de progression et appeler QApplication::postEvent depuis le thread de calcul.
    - utiliser un QObject créé dans le thread de calcul qui servira d'intermédiaire pour envoyer des signaux de type Qt::QueuedConnection au thread principal (je déconseille de faire hérité ton thread de calcul de QObject, c'est moche de tout faire hériter de QObject quand ce n'est pas nécessaire).

    Pourquoi ne veux tu pas utiliser QtConcurrent. Si tu ne dois lancer qu'une simple fonction, c'est ce qu'il y a de plus simple.
    Sinon, +1 pour OpenMP.

  4. #4
    Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 3
    Points : 2
    Points
    2
    Par défaut
    Merci pour ces conseils.

    Je suis donc passé à QtConcurrent, ce qui me permet d'utiliser les signaux/slots mais j'ai un maintenant un soucis d'utilisation que je n'avais pas avec boost (surement parce que je me sers mal de Qt). J'ai une boucle sur des répertoires dont je ne connais pas le nombre par avance. Pour chaque itération, je souhaite donc lancer un thread avec QtConcurrent::run, en passant en paramètre un foncteur du style (en simplifiant) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    class FunctorSRE
    {
    public:
       FunctorSRE     ( int Param1, int Param2, int Param3 );
       void operator()()    { doCalcAndSaveSRE(); }
    private:
        void    doCalcAndSaveSRE();
    };
    Dans ma boucle, je fais donc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    FunctorSRE    MyFunctor ( 1, 2, 3 );
    et je ne sais pas comment appeler le run après pour lancer l'opérateur () (il me faudrait un boost::ref ?)

    De plus, l'objet MyFunctor est détruit en sortie de la boucle, alors que potentiellement le thread n'est pas encore lancé. Comment faire ?

  5. #5
    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 gbdivers Voir le message
    je déconseille de faire hérité ton thread de calcul de QObject, c'est moche de tout faire hériter de QObject quand ce n'est pas nécessaire
    Je ne suis pas d'accord. Mettre le calcule dans un QObject à de très gros avantages. A condition d'exploiter les Signal/Slot bien sure.
    1- découpage du module de calcule en boite noire. On peut le remplacer facilement.
    2- L'association du module à un thread est dynamique. On peut le tester en mono-thread et multi-thread et deux lignes.
    3- pas de reimplementation de QThread. Juste une utilisation de son eventloop.

    http://qt-labs.developpez.com/thread...-movetothread/
    http://yan-verdavaine.developpez.com...t_movetothread (pas encore finalisé)

  6. #6
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par yan Voir le message
    Je ne suis pas d'accord. Mettre le calcule dans un QObject à de très gros avantages. A condition d'exploiter les Signal/Slot bien sure.
    1- découpage du module de calcule en boite noire. On peut le remplacer facilement.
    2- L'association du module à un thread est dynamique. On peut le tester en mono-thread et multi-thread et deux lignes.
    3- pas de reimplementation de QThread. Juste une utilisation de son eventloop.

    http://qt-labs.developpez.com/thread...-movetothread/
    http://yan-verdavaine.developpez.com...t_movetothread (pas encore finalisé)
    Pour un puriste C++, QObject reste un gros "void*" qui ne dit pas son nom. Bref, d'accord avec gbdivers pour dire que c'est moche. Ce genre de framework contamine tout ce qu'il touche rendant le reuse complexe voire impossible.

  7. #7
    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 3DArchi Voir le message
    Pour un puriste C++, QObject reste un gros "void*" qui ne dit pas son nom.
    je ne voie pas le rapport avec "void *"

    Bref, d'accord avec gbdivers pour dire que c'est moche.
    La discution sur les super object existe déjà :p

    Ce genre de framework contamine tout ce qu'il touche rendant le reuse complexe voire impossible.
    Donne moi un framework que n’est pas contaminant.
    Au final, il suffit de bien découper le code pour limiter la contamination comme tu dit.

  8. #8
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    Pour faire la connexion entre le thread de calcul et le thread principal, j'aurais simplement crée une classe dédié à la connexion et seul cet objet hériterait de QObject.
    Le gros avantage que j'y vois, c'est que l'on peut utiliser n'importe quelle lib de thread derrière puisque la partie Qt est complètement découplé de la partie thread. On manipule simplement cette classe de connexion dans le thread mais le thread lui même n'a pas besoin d'avoir une dépendance à Qt.

    Mais c'est bien dans le cas de l'utilisation d'une autre lib pour les threads (ou se laisser la possibilité dans le futur de supprimer totalement la dépendance à Qt, par exemple sur une application tournant sur un serveur de calcul)

  9. #9
    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 gbdivers Voir le message
    Pour faire la connexion entre le thread de calcul et le thread principal, j'aurais simplement crée une classe dédié à la connexion et seul cet objet hériterait de QObject.
    Comment gère tu la connexion dans le sens thread principale - thread de calcul s'il n'y as pas d'eventloop dans le thread?

    Dans l'autre sens, y as pas problème et les signaux sont threadsafe.

    Citation Envoyé par gbdivers Voir le message
    Mais c'est bien dans le cas de l'utilisation d'une autre lib pour les threads (ou se laisser la possibilité dans le futur de supprimer totalement la dépendance à Qt, par exemple sur une application tournant sur un serveur de calcul)
    Si tu découpe bien le code, rien n'empêche de virer Qt.
    Par exemple tu fait une classe calcule et une classe qui l'interface héritant de QObject.
    Cela peut s’apparente à du pimpl et la classe interne est Qt free et réutilisable. Y as beaucoup de manière différente de faire.

    Après ça dépend des cas et des besoins. Je voulais juste faire remarquer que dans le cas multithread Qt propose des choses très intéressante grace au QObject.

  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
    Citation Envoyé par petebull1976 Voir le message
    Pour chaque itération, je souhaite donc lancer un thread avec QtConcurrent::run, en passant en paramètre un foncteur du style
    QtConcurrent::map est surement plus adapté.
    Le foncteur utilisé doit être copiable. Regarde l'exemple ici :
    http://yan-verdavaine.developpez.com...p#qtconcurrent

  11. #11
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    Par exemple tu fait une classe calcule et une classe qui l'interface héritant de QObject.
    Cela peut s’apparente à du pimpl et la classe interne est Qt free et réutilisable. Y as beaucoup de manière différente de faire.
    On est d'accord mais dans ce cas aussi tu sépares tes classes de calcul et la classé héritant de QObject qui sert d'interface.
    Dans tous les cas, l'héritage de QObject est une relation trop forte pour faire dépendre la classe calcul de QObject (sauf si on écrit 100% Qt et si on prévoit pas d'évolution sans Qt)

    Après ça dépend des cas et des besoins. Je voulais juste faire remarquer que dans le cas multithread Qt propose des choses très intéressante grace au QObject.
    On est d'accord sur ce point, c'est pour ça que j'avais parlé de QtConcurrent dans mon premier post.

  12. #12
    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 gbdivers Voir le message
    sauf si on écrit 100% Qt et si on prévoit pas d'évolution sans Qt
    C'est une des contraintes de départ d'un projet. Faire une abstraction du framework à un coût en bug potentielle, temps, complexité,...

    Personnellement, si j'utilise un framework, je considère que c'est pour l'exploiter au maximum. Une partie du code dépendra du framework choisie quoi qu'il arrive. Et le changement impose une partie de recordage et d'adaptation. Ce qui n'empêche pas de faire du code réutilisable quand c'est possible ou que cela as un sens ou d'utiliser une lib tierce non Qt sans difficulté.

Discussions similaires

  1. Gestion d'une IHM Qt depuis un thread POSIX
    Par lulafitt dans le forum Multithreading
    Réponses: 1
    Dernier message: 02/03/2011, 01h28
  2. Gestion d'une IHM Tkinter par un thread
    Par Julien38 dans le forum Tkinter
    Réponses: 1
    Dernier message: 23/05/2009, 23h44
  3. Réponses: 0
    Dernier message: 01/08/2008, 11h57
  4. [SWING][THREAD]Méthodes pour afficher une Frame
    Par pompidouwa dans le forum Agents de placement/Fenêtres
    Réponses: 3
    Dernier message: 05/05/2004, 11h35
  5. Réponses: 6
    Dernier message: 03/03/2004, 15h31

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