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 :

Thread d'acquisition de données depuis carte PCI [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 Thread d'acquisition de données depuis carte PCI
    Bonjour,

    je travail sur un projet d'acquisition de données à partir d'un carte PCI.
    Les fonctions données dans le SDK de la carte me permettent de réceptionner un buffer de données dès qu'un déclencheur (trigger) est atteint.
    L'acquisition de ces données se fait grâce à la fonction qu'on apellera XDA_Get().

    Lorsque cette fonction est appelée, elle attend (indéfiniment) jusqu'à ce que le déclencheur soit atteint.

    Etant donnée que cette acquisition doit se faire indéfiniment, je l'ai mise dans une boucle infinie, dans un QThread.

    Mon problème est maintenant d'arrêter proprement ce thread afin que je puisse couper l'acquisition, et lancer une petite fonction (propre à l'utilisation de cette carte) juste avant l'arrêt du thread.

    J'ai essayé quit() mais ça ne s'arrête pas, et terminate() est largement déconseillé pour ce genre d'utilisation, même si cela fonctionne.

    Comment puis-je lancer une fonction lors de l'arrêt d'un thread ?
    Comment puis-je stopper mon thread proprement ?
    Les slots pourraient-ils m'aider à exécuter une fonction juste avant de stopper le thread ?

    Voici mon fichier analyse.cxx
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    #include "analyse.hxx"
    #include <QDebug>
    #include <QThread>
    #include "./Include/XDADAQ.h"
    #include <iostream>
     
    using namespace std;
     
    Analyse::Analyse(QThread * parent) : QThread(parent) {}
     
    void Analyse::run() {
        cout << "[Acquisition]" << endl;
        acquisition();
    }
     
    void acquisition() {
        do {
            /* Parametrage */
            XDA_Get(); //Attente du trigger
        }while(true);
    }
    analyse.hxx
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    #ifndef ANALYSE_H
    #define ANALYSE_H
    #include <QThread>
    #include "./Include/XDADAQ.h"
     
    class Analyse : public QThread
    {
        Q_OBJECT
        protected:
            void run();
     
        public:
            /* Constructeur */
            Analyse(QThread * parent = 0);
            ~Analyse(){}
    };
     
    #endif // ANALYSE_H
    Merci beaucoup !

  2. #2
    Rédacteur

    Inscrit en
    Novembre 2006
    Messages
    1 272
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 272
    Par défaut
    Tu crées un variable membre dans ton Thread genre:
    Dans le do-while de ta fonction acquisition() tu fais ça:
    Apres tu crées un slot du genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void Analyse::stop()
    {
    m_run=false;
    }
    Enfin avant de créer et de lancer ton thread tu le connect avec le signal qui te permetra de d'arrêter ton thread.
    Vous voulez participer aux Tutoriels, FAQ ou Traductions et faire partie de l'équipe Qt de Developpez.
    N'hésitez pas à me contacter par MP.

  3. #3
    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
    Vue quelle est bloquante, je ne voie pas trop.
    Quand doit tu stopper le get? N'y aurait il pas une autre fonction non bloquante?

  4. #4
    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
    Merci superjaja pour tes idées je vais essayer.
    Mais ton slot me permettra quand même de terminer ce thread ?

    Yan le fait que tu me parles de fonction "bloquante" me fait penser à un truc. On peut paramètrer cette carte par le biais de cette fonction pour faire une acquisition sur un mode asynchrone ou synchrone. D'après la doc le mode asynchrone met l'enregistrement sur buffer en arrière plan et permet de travailler en même temps sur la carte. Je pensais pas que ça pouvait avoir un rapport avec cette fonction mais surment que si ! Je vais approfondir le sujet.

    Merci pour votre aide, je vous tiendrais au courant

  5. #5
    Rédacteur

    Inscrit en
    Novembre 2006
    Messages
    1 272
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 272
    Par défaut
    Citation Envoyé par yan Voir le message
    Vue quelle est bloquante, je ne voie pas trop.
    Quand doit tu stopper le get? N'y aurait il pas une autre fonction non bloquante?
    En fait je crois que je n'avais pas bien compris ton problème. Si tu attends un trigger, que ta fonction XDA_Get() est bloquante et que tu l'attends qu'une fois. Et bien tu n'a rien à faire tu enlèves ta boucle do-while et un fois que le trigger se déclenche le thread va s'arrêter tout seul.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    void Analyse::run() {
    XDA_Get();
    }
    Finalement tu as jsute àlancer le thread. LeThread attend le trigger indéfiniment grâce à ta fonction XDA_Get() et des qu'il se déclenche le thread s’arrête. Si j'ai bien compris ton problème c'est tout ce que tu as a faire.
    Vous voulez participer aux Tutoriels, FAQ ou Traductions et faire partie de l'équipe Qt de Developpez.
    N'hésitez pas à me contacter par MP.

  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
    Souvent quand on peux utiliser une fonction asynchrone, on peut donner un callback qui sera appelé quand le traitement est fini.
    S'il n'y as pas de callback, comme tu peux utiliser en asynchrone, plus besoin de thread . Passe plutôt par l'eventloop

  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
    superjaja: tu as bien compris ce que je veux faire sauf que mon programme doit collecter des données indéfiniment donc doit attendre un nombre illimité de trigger, c'est pour ça que j'ai mis une boucle infinie.

    yan: ma fonction start n'a pas de callback, parcontre j'ai une fonction wait() qui me permet de déterminer une fonction callback. Voici la doc.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    Prototype
    C: i32 XDA_Ain_Wait(i32 device, i32 (*cbfunc)(i32 count, void * buffer))
    VB: NA
     
    Description
     
    Block until either the "buffer full" event or a timeout event occurs. The timeout is set by
    XDA_BOARD_PARM_TIMEOUT. If a callback is specified, it will be invoked upon receipt
    of the half-buffer full event, and the return value will be interpreted as a 'iterate' or 'exit' flag.
    A positive non-zero value will cause this routine to continue collecting data (and invoking the
    callback on each half-buffer event); a negative or zero value will cause this routine to
    terminate data collection and return control to the caller. If the callback is NULL, control will
    be returned to the caller when either event occurs.
    Merci pour votre aide !

  8. #8
    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
    Au passage yan, j'ai cherché un peu partout le principe de fonctionnement d'un eventloop d'un thread mais je dois t'avouer que je ne comprend pas concrètement comment ça fonctionne et à quoi ça sert.
    Je sais juste qu'on appel exec() et quit() et que cette boucle "attend" des évènements Qt avant d'agir. J'ai lu aussi que quit() ne permet juste de sortir de l'eventloop et non pas du thread.

    Vos réponses m'aident beaucoup

  9. #9
    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
    Le problème c'est que si c'est bloquant, tu ne peux pas l'arrêter comme cela. Que ce soit dans un thread ou autre. Par contre il semble que tu peux avoir un timeout.
    Si le timeout est petit (1s par exemple) tu peux l'exploiter pour boucler et stopper correctement thread.

    Le top serait une fonction qui te dit que tu peux lire des données. Et qui ne bloque pas bien sure.

    Quand doit tu stopper le thread?
    es ce que tu sait s'il y as des restriction sur le multithread pour utilise la carte?

    L'eventloop est juste une boucle qui va exécuter des évènements. Si tu était asynchrone, tu pourrais utiliser ce système.

  10. #10
    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 cherché un peu plus profondément et j'ai trouvé la solution.

    En faite j'utilise la fonction d'acquisition de la carte en mode asynchrone, ce qui rend l'attente non bloquante. Une fois cette fonction lancée, une boucle sans fin attend les conditions d'arrêt de la carte (échantillons récoltés ou erreurs). Du coup j'ai juste eu à utiliser votre idée qui était de mettre un boolein dans la condition de la boucle. Et ça fonctionne à merveille !

    Mais j'ai une question qui me trotte sur la haricot.

    Lorsqu'on retourne d'un thread ou si le thread arrive normalement à la fin de son exécution, est-ce que le thread est automatiquement détruit ? Ou on peut le réutiliser ?
    La doc n'est pas très explicite de ce point de vue là.

    Merci à tous !

  11. #11
    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
    Lorsqu'on retourne d'un thread ou si le thread arrive normalement à la fin de son exécution, est-ce que le thread est automatiquement détruit ? Ou on peut le réutiliser ?
    Le QThread oui mais il recréé un thread en interne.
    Qt propose beaucoup de chose. Tout dépend du problème.
    Si tu est asynchrone, tu n'as plus besoin de thread.
    IL te suffit de regarder régulièrement s'il y as une donnée dans le thread principal.

    Il exist QObject::startTimer qui pourrai te simplifier la vie ou un QTimer

  12. #12
    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
    C'est vrai que vu comme ça le thread n'est plus du tout utile.
    J'ai une autre question: si un thread se termine ou retourne quelque chose, peut-on relancer son exécution en appelant start() ?

    Merci

  13. #13
    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
    peut-on relancer son exécution en appelant start() ?
    Si tu parle de QThread, oui

  14. #14
    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
    Effectivement je parle de QThread. Que fait le thread entre le temps où il a terminé et celui où on le lance ?

  15. #15
    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
    Effectivement je parle de QThread. Que fait le thread entre le temps où il a terminé et celui où on le lance ?
    Normalement détruit et recréé. Mais c'est transparent pour nous.

  16. #16
    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
    Merci beaucoup pour tes réponses.

    Je pense qu'il faudrait faire un gros tuto bien complet pour expliquer en profondeur le potentiel de QThread, QConcurrent, QThreadPool, etc, pour éviter par exemple l'utilisation abusive de QThread lorsque c'est inutile.

  17. #17
    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
    Merci beaucoup pour tes réponses.

    Je pense qu'il faudrait faire un gros tuto bien complet pour expliquer en profondeur le potentiel de QThread, QConcurrent, QThreadPool, etc, pour éviter par exemple l'utilisation abusive de QThread lorsque c'est inutile.
    c'est en cours (depuis 2 ans )

  18. #18
    Rédacteur

    Inscrit en
    Novembre 2006
    Messages
    1 272
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 272
    Par défaut
    Citation Envoyé par yan Voir le message
    c'est en cours (depuis 2 ans )
    En même temps tu arrives bientôt au bout de ce tuto...
    Sinon Yan je ne crois pas que tu avais prévue des choses sur le mécanisme de destruction des QThread ???
    Vous voulez participer aux Tutoriels, FAQ ou Traductions et faire partie de l'équipe Qt de Developpez.
    N'hésitez pas à me contacter par MP.

  19. #19
    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 superjaja Voir le message
    En même temps tu arrives bientôt au bout de ce tuto...
    yep.
    Il me reste les QWaitCondition et les state machine .
    Les state machine sont affreusement puissante et simplifie encore plus le multithreading . Je n'y avais jamais pensé avant ce debut de semaine (ca fait du bien un peu de Qt aprés quelques mois de pause) quand j'ai découvert que QStateMachine::postEvent etait threadsafe!!!

    Je suis même étonné qu'il n'y as aucun post de Qt à propos de cela.

    Citation Envoyé par superjaja Voir le message
    Sinon Yan je ne crois pas que tu avais prévue des choses sur le mécanisme de destruction des QThread ???
    Comment cela?

  20. #20
    Rédacteur

    Inscrit en
    Novembre 2006
    Messages
    1 272
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 272
    Par défaut
    Citation Envoyé par yan Voir le message
    Comment cela?
    En rapport avec ce post
    Citation Envoyé par yan Voir le message
    Le QThread oui mais il recréé un thread en interne.
    Qt propose beaucoup de chose.
    Vous voulez participer aux Tutoriels, FAQ ou Traductions et faire partie de l'équipe Qt de Developpez.
    N'hésitez pas à me contacter par MP.

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 19/03/2011, 23h24
  2. Pb acquisition de données carte PXI
    Par automating dans le forum LabVIEW
    Réponses: 5
    Dernier message: 29/07/2010, 12h22
  3. Acquisition de données sur carte "addi-data"
    Par semvarde dans le forum LabVIEW
    Réponses: 1
    Dernier message: 02/06/2010, 13h32
  4. Réponses: 1
    Dernier message: 30/07/2009, 00h43

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