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 :

QWaitCondition sans QMutex ? [QThread]


Sujet :

Multithreading

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 112
    Par défaut QWaitCondition sans QMutex ?
    Bonjour,

    j'ai plusieurs thread au sein d'un même programme qui effectuent des tâches totalement différentes les unes des autres. Les thread sont asynchrones entre eux, c-à-d qu'on ne peut pas prévoir (sauf avertir via les signaux) quand un thread va rendre le résultat de son exécution à un autre thread pour que lui même effectue un travail dessus.

    Etant donné que l'exécution de mes thread est asynchrone, j'utilise les signaux pour envoyer les informations entre les thread (pointeurs d'objets) et je fais appel à start() afin de relancer la méthode run() du thread adéquat qui contient l'algorithme de traitement (qui ne boucle pas indéfiniment jusqu'à une demande de terminaison de thread ou jusqu'à une certaine condition).

    Donc pour l'instant mes threads (pas tous) s'exécutent, renvoient les résultats via les signaux, meurent, et son relancés par la méthode start(), autant de fois qu'un traitement est à effectuer.

    Vu que je n'ai pas besoin de mutex, parce que je n'ai pas d'accès concurrent à une même donnée, je n'ai pas l'utilité de QWaitCondition qui demande un QMutex.

    Comment puis-je réveiller ou mettre en attente les thread jusqu'à ce qu'il reçoivent l'ordre de s'exécuter ?

    J'essaye aussi d'éviter qu'un thread prenne du temps CPU pour rien, ou quoi que ce soit d'autre qui serait du temps perdu, parce que la machine sur laquelle s'exécutera le programme est doté d'un P4 1Go RAM DDR2 --'.

    Merci à tous !

  2. #2
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 035
    Par défaut
    Salut.

    j'utilise les signaux pour envoyer les informations entre les thread (pointeurs d'objets)
    To envoie des pointeurs par des signaux entre les thread ?
    Tu n'utilise pas d'eventloop dans les thread ?

    Un peu de lecture
    http://qt-labs.developpez.com/thread...-movetothread/

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 112
    Par défaut
    To envoie des pointeurs par des signaux entre les thread ?
    Ouai j'ai rien trouvé de mieux pour échanger des informations entre thread.

    Tu n'utilise pas d'eventloop dans les thread ?
    Ya quasiment rien sur le net qui explique concrètement l'utilité de l'eventloop ainsi que son fonctionnement, du coup non je n'en utilise pas dans mes thread.
    Quand on cherche Tuto Qt sur le net on tombe à 98% sur de l'interface graphique, d'ailleurs ce sont souvent les même tutos recopiés ou traduits...

    Et la petite lecture je l'ai déjà faite...

    Merci Yan

  4. #4
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 035
    Par défaut
    Citation Envoyé par alexgille Voir le message
    Ouai j'ai rien trouvé de mieux pour échanger des informations entre thread.
    Ce sont de gros objet que tu envoie? il faut faire très attention à la durée de vie de tes pointeur. Sinon autant ne pas utiliser de pointeur.

    Si tu n'as pas d'eventloop comment tu fait pour envoyer un objet d'un thread à l'autre? Si c'est en ajoutant un slot sur le QThread, il faut savoir que le QThread n'est que l'interface d'un thread et s’exécute pas dans ce thread. Donc le slot n'est pas exécuté dans le thread (sauf si t'as utilisé movetothread sur le QTHread. Ce qui n'est pas bien)

    Es ce que tu peux expliquer un peu ce que tu cherche à faire?

    As tu regardé les exemple de sur QSemahore et QWaitCOndition?

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 112
    Par défaut
    Ton histoire d'eventloop m'intéresse pour les histoire de signaux/slots et d'attente bloquante...
    Si tu pouvais me faire part de ta science sur les thread et les eventloop ça serait cool !

    Merci !

    L'objet envoyé via les signaux est un pointeur vers une classe qui contient essentiellement un tableau de 10millions de double. Je fais très attention à mes pointeurs, je sais le dangers que ça représente...

    Si tu n'as pas d'eventloop comment tu fait pour envoyer un objet d'un thread à l'autre?
    Comme tu le dis, je fais un signal d'un côté, un slot de l'autre, avec un slot qui effectue des initialisations de pointeur avant le lancement du thread.

    J'ai fais des thread comme j'ai pu, malgré que ce soit barbare, il n'y a presque aucun tuto qui explique comment bien implémenter un petit programme multithreadé utilisant les signaux/slot etc etc...

    Je t'explique le fonctionnement du programme.

    - J'ai un thread qui doit faire une acquisition de donnée sur une carte PCI.
    - Une fois que ce thread reçoit une impulsion de la carte PCI, il envoi le pointeur du buffer à un second thread qui s'occupe de stocker les données dans une file d'attente (FIFO).
    - Dès qu'il le peut, ce thread de stockage sort un un buffer de sa file d'attente et l'envoi au thread d'analyse qui analyse la courbe acquise avec la carte PCI.
    - Une fois que le thread d'analyse a terminé son analyse, il renvoi le pointeur d'un objet (Pulse) au thread de stockage.
    - Lorsque le thread de stockage reçoit ce pointeur d'objet, il effectue des opérations sur l'objet reçu, supprime l'objet, puis ressort un buffer dans sa file d'attente si il le peut et l'envoi au thread d'analyse.
    - Si la liste d'attente est vide, le thread de stockage attend l'instruction de stockage d'un nouveau buffer.
    - Le thread de stockage attend indéfiniment un nouveau à stocker et à envoyer au thread d'analyse.
    - Le thread d'analyse attend un buffer à analyser. Il peut se terminer puis se relancer, ou attendre indéfiniment jusqu'à la terminaison du programme.

    Voili voulou.

    Merci !

  6. #6
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 035
    Par défaut
    Alors ce que je te propose :
    1- vire ce pointeur de tes signaux et utilise soit un QSharedPointeur soit pas de pointeur du tout
    2-remplace tes thread par des QObject et fait fonctionner le tout sans thread avec des échange par signal/slot.Tes classe peuvent utiliser l'eventloop si besoin(Tu peut utiliser starttimer pour cela)
    3- quand tout marche instancie des QThread(exécute une eventloop par defaut) et applique des movetothread sur tes QObject.

    Tu doit surement pouvoir regrouper certain QObject dans un même thread. Attention au accès concurrent s'il y en as.

    j'ai commencer un article sur le thème. y as pas mal de faute d'ortho mais l'article est sur la fin. Si cela peut t'aider.
    http://yan-verdavaine.developpez.com/wiki/doku.php

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 112
    Par défaut
    QObject permet l’exécution de deux portion de code en parallèle ?

    L'acquisition sur la carte ne peut pas être suspendu en attendant la fin de l'analyse...
    A vrai dire je ne sais pas trop comment fonctionne QObject...

    En plus j'ai pas d'accès concurrent aux données, le truc qui m'importe c'est que l'acquisition soit exécutable en parallèle de l'analyse des courbes acquises.

    Mais merci pour tes réponses !

  8. #8
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 035
    Par défaut
    Citation Envoyé par alexgille Voir le message
    QObject permet l’exécution de deux portion de code en parallèle ?

    L'acquisition sur la carte ne peut pas être suspendu en attendant la fin de l'analyse...
    A vrai dire je ne sais pas trop comment fonctionne QObject...

    Mais merci pour tes réponses !
    http://qt.developpez.com/faq/?page=Thread
    Le but est d'exploiter le système de signal/slot entre les thread.

    Sinon, précise ce que tu n'as pas compris

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 112
    Par défaut
    J'ai utilisé les signaux/slots pour transmettre des données entre les thread parce que c'est tout ce que j'ai trouvé ... le truc qui m'importe c'est que l'acquisition puisse tourner en parallèle de l'analyse des courbes.

    En cours je suis en train de voir les thread POSIX sous unix, j'aimerai faire un petit peu pareil mais en moins chiant à coder :p.

    Je te détail la logique de ma question.

    Pour l'instant, l'implémentation des QThread dans mon programme ce fait comme ça:

    J'ai plusieurs objets qui héritent de QThread dans lesquels j'ai un algorithme que j'ai mis dans la méthode run().

    A chaque fois que j'ai besoin d’exécuter ce thread j'utilise le mécanisme signal/slot pour transmettre les pointeurs et je fais appel à la méthode start() du thread que je veux réveiller afin qu'il exécute l'algorithme en parallèle aux autres thread du programme.

    Il n'y pas de thread qui travaillent à plusieurs sur une même donnée, ni même plusieurs thread qui effectuent un travail similaire. J'ai un thread par tâche et c'est tout.

    Ma question à l'origine était, c'est pas un peu batard de faire des start() dans tous les sens ? Sachant que le thread géré par le QThread meurt à la fin de run() normalement il faudrait que j'endorme le thread jusqu'à ce qu'il ai quelque chose à faire non ?

  10. #10
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 035
    Par défaut
    j'ai bien compris ce que tu a fait. Mais c'est plutôt bancale et tu as des accès concurrent possible. Comme ta FIFO. + t'as de thread + t'as de bug potentiel. Utiliser des thread unix ou autre ne changerons rien puisque c'est la même chose.

    Ce que je t'ai essayé de t'expliqur est une architecture qui permet de faire du multithread de manière propre grâce à Qt. Mais j'ai l'impression que tu n'as pas compris mes explication

  11. #11
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 112
    Par défaut
    Ne t'inquiète pas je comptais pas mélanger du pthread avec du Qt hahaha ça serait l’hécatombe !

    En faite, ce que j'ai pas compris :
    1- Tu me propose de supprimer totalement mes pointeurs, mais comment je peux transférer un objet d'un thread vers un autre ?

    2- Tu me propose d'utiliser QObject, mais quelle est la différence entre faire un QThread directement et faire un QObject puis l'assigner à un QThread ?

    Demande moi des précisions au sujet du programme, c'est un projet étudiant

  12. #12
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 035
    Par défaut
    1- Tu me propose de supprimer totalement mes pointeurs, mais comment je peux transférer un objet d'un thread vers un autre ?
    en faite c'est surtout unpointeur brut. Déjà utiliser QSharedPointeur serait bien mieux et tu ne gère plus le delete.
    Ne as oublie d'utiliser http://qt.developpez.com/doc/latest/...gisterMetaType.
    En mémoire ce que tu passe fait a peu prés combien? 1 Mo?

    2- Tu me propose d'utiliser QObject, mais quelle est la différence entre faire un QThread directement et faire un QObject puis l'assigner à un QThread ?
    L'éxécution du slot dans le bon thread, minimiser le nombre de thread et équilibrer leurs exécution.
    En passant par des QObject te permet aussi de réfléchir en monothread et de passer très simplement en multithread. La clef est le syteme signal/slot ou
    • signal : est threadsafe
    • slot : s'execute dans le thread associé avec le Object.



    Demande moi des précisions au sujet du programme, c'est un projet étudiant
    j'ai trouvé ta description claire. les acteurs me semblent bien distingué.

  13. #13
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 112
    Par défaut
    En faite, jusqu'à ce que le fichier final soit enregistré (c a d après l'analyse) le pointeur pointe vers un objet qui contient un buffer de double qui peut aller de 10 000 doubles à 40 Millions de double...donc niveau mémoire c'est énorme...pour ça que j'ai pensé au pointeur ...

    L'éxécution du slot dans le bon thread
    Pourquoi ? Normalement le slot n'est pas exécuté par le QThread qui contient ce slot ?

    PS: J'ai utilisé qRegisterMetaType

  14. #14
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 035
    Par défaut
    Citation Envoyé par alexgille Voir le message
    En faite, jusqu'à ce que le fichier final soit enregistré (c a d après l'analyse) le pointeur pointe vers un objet qui contient un buffer de double qui peut aller de 10 000 doubles à 40 Millions de double...donc niveau mémoire c'est énorme...pour ça que j'ai pensé au pointeur ...
    ok. C'est surtout qu'un pointeur nue entre thread peut facilement poser un problème. AVec QSHaredPointeur il y aura un compteur de reference associé à ton pointeur.

    Pourquoi ? Normalement le slot n'est pas exécuté par le QThread qui contient ce slot ?
    Oui mais QThread n'est pas exécuté dans le thread qu'elle interface mais dans le thread qui la créé. Donc surement le thread principale pour toi.
    Dans ton cas les QThread se retrouvent entre les deux threads (slot->thread parent et le run->thread interfacé).Et il te faut protéger de partout.
    Que risque t'il de se passer si tu ajoute un buffer dans ta fifo alors qu'elle est en train de l'envoyer ?

  15. #15
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 112
    Par défaut
    Que risque t'il de se passer si tu ajoute un buffer dans ta fifo alors qu'elle est en train de l'envoyer ?
    Bah je crois que ça va faire boum ..

    Pour mon problème, je dois:
    1 - transformer mes QThread en QObject.
    2 - Créer des QThread qui serviront à accueillir ces QObject.
    3 - Assigner les QObject aux QThread grâce à moveToThread().

    C'est bien ça ?

  16. #16
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 035
    Par défaut
    Citation Envoyé par alexgille Voir le message
    Bah je crois que ça va faire boum ..

    Pour mon problème, je dois:
    1 - transformer mes QThread en QObject.
    2 - Créer des QThread qui serviront à accueillir ces QObject.
    3 - Assigner les QObject aux QThread grâce à moveToThread().

    C'est bien ça ?
    yep et tu utilise les signal/slot entre tes QObject.

  17. #17
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 112
    Par défaut
    Question bête .. je les instancies où les QThread ? Ya pas une histoire avec le thread parent ?

  18. #18
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 035
    Par défaut
    Citation Envoyé par alexgille Voir le message
    Question bête .. je les instancies où les QThread ? Ya pas une histoire avec le thread parent ?
    Un peux comme tu veux mais je dirais au même endroit que tes QObject.

  19. #19
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 112
    Par défaut
    Si j'ai bien compris, le QThread c'est ce qui me permet de faire des exécutions parallèle, et le QObject c'est ce qui s'exécute dans le QThread ?

    Donc je peux attribuer un QObject à n'importe quel QThread il fera le même travail ?

  20. #20
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 035
    Par défaut
    Citation Envoyé par alexgille Voir le message
    Si j'ai bien compris, le QThread c'est ce qui me permet de faire des exécutions parallèle, et le QObject c'est ce qui s'exécute dans le QThread ?

    Donc je peux attribuer un QObject à n'importe quel QThread il fera le même travail ?
    Oui. Ce qui change c'est le thread qui exécute le slot du QObject.

    A mon avis tu as besoin de 2 QThread:
    1- pour l’acquisition. A la limite lui pourrait être un QThread.
    2- pour les autres QObject.


    Dans ce système, chaque QThread exploite une eventloop. Donc attention à ne pas la bloquer inutilement (boucle infinie) et à y penser quand tu associe plusieurs QObject à un même QTHread.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 3 123 DernièreDernière

Discussions similaires

  1. Comment récupérer le nom du fichier sans l'extension ?
    Par altahir007 dans le forum Langage
    Réponses: 16
    Dernier message: 13/11/2009, 13h20
  2. [TP]Compiler un prog sans entrer dans TP7
    Par poppels dans le forum Turbo Pascal
    Réponses: 11
    Dernier message: 23/10/2002, 18h46
  3. MDI sans MFC, possible ?
    Par delire8 dans le forum MFC
    Réponses: 4
    Dernier message: 17/06/2002, 07h38
  4. [Kylix] Fiches sans bordure
    Par alex dans le forum EDI
    Réponses: 4
    Dernier message: 28/04/2002, 21h19

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