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 :

Gérer l'état d'exécution d'un QThread


Sujet :

Multithreading

  1. #1
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2014
    Messages
    374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Novembre 2014
    Messages : 374
    Points : 47
    Points
    47
    Par défaut Gérer l'état d'exécution d'un QThread
    Bonjour à tous,

    Mon projet consiste à faire une interface graphique pour récupérer des données venant d'un matériel extérieur à un Ordinateur.
    Pour ne pas freezer mon interface j'ai créé un QThread dans ma classe principale à partir de ma classe principale pour l'affichage.

    Pour que ce thread ne se termine pas, j'ai mis un boucle do while() avec sleep pour la condition de non appel de fonction d'acquisition, d'attente si on préfère.
    Lorsqu'on appuie sur un bouton d'acquisition, la variable "num_fonction_acq" passe de 1 à 4 selon les modes d'acquisitions.

    Cette fonction est lancé après le start, je l'ai mise dans run().

    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
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    void Communication_spectro::Acquisition()
    {
        do{
     
            switch (num_fonction_acq) {
     
            case 0:
              Sleep(10000);
              //this->wait(10000 = 100000000);
              cout << "pause" << endl;
              break;
     
              cout << "essai1" << endl;
            //Fonction d'acquisition du bruit
            case 1:
              //cout << "etape 1" << endl;
              Acquisition_bruit();
              num_fonction_acq = 0; //remise à zero d'une demande de fonction
              emit(signal_acq_bruit()); //affichage des données à l'écran
     
              //cout << "etape 2" << endl;
              break;
     
            //Fonction d'acquisition unique
            case 2:
              Acquisition_unique();
              num_fonction_acq = 0;
              break;
     
            //Fonction d'acquisition unique + moyenne
            case 3:
              Acquisition_unique_nb_acq();
              num_fonction_acq = 0;
              break;
     
            //Fonction d'acquisition continue
            case 4:
              Acquisition_continue();
              num_fonction_acq = 0;
              break;
     
            default:
     
              break;
            }
     
        }
        while (stop_thread == 0);
     
     
        //Fin de communication avec la spectromètre
        DoubleArray_Destroy(spectrumArrayHandle);
        DoubleArray_Destroy(wavelengthArrayHandle);
     
        Wrapper_closeAllSpectrometers(wrapperHandle);
        Wrapper_Destroy(wrapperHandle);
     
    }
    Le but avec un thread permanent est de s'affranchir de la contrainte de temps que représente la création d'un connexion USB avec le matériel.

    Comment est-ce que je pourrais faire afin de faire passer le QThread du mode sommeil avec Sleep() au mode Running?

  2. #2
    Rédacteur
    Avatar de Amnell
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2009
    Messages
    1 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 840
    Points : 5 545
    Points
    5 545
    Par défaut
    Bonjour,

    Je suppose que vous avez la main sur l'assignation de num_function_acq par conséquent ?
    Si c'est le cas, QWaitCondition pourra probablement vous aider : http://doc.qt.io/qt-5/qwaitcondition.html

    Bonne journée,
    Louis

  3. #3
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2014
    Messages
    374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Novembre 2014
    Messages : 374
    Points : 47
    Points
    47
    Par défaut
    Oui j'ai la main dessus.

    Effectivement mais je cherche comment implémenter un QWaitCondition

  4. #4
    Rédacteur
    Avatar de Amnell
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2009
    Messages
    1 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 840
    Points : 5 545
    Points
    5 545
    Par défaut
    Bonjour,

    Dans ce cas, vous pouvez vous en servir. Du côté du thread, il faudrait utiliser le wait() de la QWaitCondition de sorte d'attendre, en remplacement du Sleep actuel. Du côté du thread où vous modifiez le num_fonction_acq, vous pouvez alors utiliser wakeOne() de sorte de sortir le thread du Sleep afin de lui faire effectuer les opérations que vous voulez.

    Bonne soirée,
    Louis

  5. #5
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2014
    Messages
    374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Novembre 2014
    Messages : 374
    Points : 47
    Points
    47
    Par défaut
    Citation Envoyé par Amnell Voir le message
    Bonjour,

    Dans ce cas, vous pouvez vous en servir. Du côté du thread, il faudrait utiliser le wait() de la QWaitCondition de sorte d'attendre, en remplacement du Sleep actuel. Du côté du thread où vous modifiez le num_fonction_acq, vous pouvez alors utiliser wakeOne() de sorte de sortir le thread du Sleep afin de lui faire effectuer les opérations que vous voulez.

    Bonne soirée,
    Louis
    Merci. Je l'ai fait cet après-midi.

    Mon souci c'est maintenant dans le respect des contrainte de temps.

    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
    22
    23
    24
    25
    26
    27
    void Communication_spectro::run()
    {
        // On lance une boucle d'événement pour que
        // les slots fonctionnent et soient exécutés
        // dans le thread
        //exec();
        //integrationTimeMicrosec = integrationTimeMicrosec * 1000; //conversion ms en µs
        spectrometerIndex = 0;
     
        wrapperHandle = Wrapper_Create();
        // The following call will populate an internal array of spectrometer objects
        nombre_spectrometres = Wrapper_openAllSpectrometers(wrapperHandle);
     
        spectrumArrayHandle = DoubleArray_Create();
        wavelengthArrayHandle = (DOUBLEARRAY_T)DoubleArray_Create();
     
        forever{
            mutex->lock();
            cout << "EN ATTENTE D'ACQUISITION" << endl;
            cout << "........................." << endl;
            acquisition_pressed->wait(mutex);
     
            Communication();
            cout << "FIN ACQUISITION" << endl;
            mutex->unlock();
        }
    }
    Il n'y a pas d'erreur dans forever?

    En fait, la fonction communication récupère un tableau de double.
    L'objet mythread contient ce tableau.

    Comment faire pour le donner à l'objet mainwindow?
    SIGNAL/SLOT?
    =>Cela prend du temps de donner un tableau de 1024 double non? -> l'affichage se situant juste après... je ne suis pas très juste pour l'affichage en terme de temps.

  6. #6
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2014
    Messages
    374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Novembre 2014
    Messages : 374
    Points : 47
    Points
    47
    Par défaut
    Par contre, je suis embêté car je dois transférer les données de mon objet thread vers l'objet de mon MainWindow !

    Je suis entrain de dire des absurdités! En fait je fais mon traitement de spectre par la suite sur l'objet qui gère l'interface graphique.

    Il faudrait que je fasse encore un thread pour les traitements de spectre ... pour être correcte.

    ----------------------

    1-Un objet pour l'affichage qui va pointer vers les données nécessaires
    2-Un thread qui récupère les données
    3-Un thread pour le traitement de spectre
    ...

    ----------------------

    Pas besoin de faire aussi complexe mais quand même, ça vaut le coup d'y réfléchir. Je suis un peu perdu dans tout ceci !!

    ----------------------

    Par contre, je suis embêté car je dois transférer les données de mon objet thread vers l'objet de mon MainWindow !
    Mon objet qui est un thread d'acquisition représente normalement les dernières données reçues.
    Mon objet d'affichage des données ne devrait lancer que seulement des traitements dans d'autres threads et ne pas les lancer dans son objet qui est l'affichage.

    =>On doit quand même faire transiter des données entre l'objet thread d'acquisition et la fenêtre principale !

    Le schéma de la contrainte de temps est la suivante :
    1-acquisition -> envoie des données -> mise en mémoires des données -> affichage
    2-acquisition -> affichage
    => Le souci c'est que je fais des traitements de spectre dans l'objet mainwindow donc je suis dans le cas1 pour le moment... à moins que je ne sache lancer des threads de traitement de spectre...

    ---------------------

    Je pense qu'il est possible de passer un tableau de double de 1024 par SIGNAL/SLOT mais comment ? et est-ce que ça prend du temps ...

  7. #7
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2014
    Messages
    374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Novembre 2014
    Messages : 374
    Points : 47
    Points
    47
    Par défaut
    On m'avait mis en garde sur la séparation affichage/traitement des données.

    Il est possible d'intégrer tout mon code d'acquisition et de traitement de spectre dans mon thread?
    Ca ne fairait pas trop "lourd" pour un thread? -> Il Faudrait peut être créer un processus non?

    =>La conclusion c'est un affichage instantané et la séparation affichage/acquisition & traitement de données.

  8. #8
    Responsable Qt & Livres


    Avatar de dourouc05
    Homme Profil pro
    Ingénieur de recherche
    Inscrit en
    Août 2008
    Messages
    26 681
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur de recherche
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2008
    Messages : 26 681
    Points : 188 810
    Points
    188 810
    Par défaut
    Citation Envoyé par joffrey575 Voir le message
    Ca ne fairait pas trop "lourd" pour un thread? -> Il Faudrait peut être créer un processus non?
    Si tu crées un processus, la communication devient plus compliquée (vive les IPC…), même si la mémoire devient bien séparée. Vraiment, un fil d'exécution est très largement suffisant pour la plupart des besoins (sauf si tu dois traiter des gigaoctets de données en 32 bits, pour éviter d'exploser la mémoire, mais ça devient rare).

  9. #9
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2014
    Messages
    374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Novembre 2014
    Messages : 374
    Points : 47
    Points
    47
    Par défaut
    Citation Envoyé par dourouc05 Voir le message
    Si tu crées un processus, la communication devient plus compliquée (vive les IPC…), même si la mémoire devient bien séparée. Vraiment, un fil d'exécution est très largement suffisant pour la plupart des besoins (sauf si tu dois traiter des gigaoctets de données en 32 bits, pour éviter d'exploser la mémoire, mais ça devient rare).
    J'ai juste un souci de répartition des tâches je pense ...

    Acquisition "classique" :
    1-le thread attend (Thread "permanant")
    2-appuie sur un bouton (Interface utilisateur)
    3-acquisition (Thread "permanant")
    4-traitement des données (Interface utilisateur) -> ceci ne devrait pas être dans l'interface utilisateur.
    5-affichage des données (Interface utilisateur)
    =>puis on attend de nouveau un événement de l'interface

    Remarque : En fait, je n'arrive pas à libérer les tableaux du thread quand je les utilises avec l'Interface utilisateur pour faire le traitement de données
    Solution : faire tout mes calculs dans le thread! c'est possible?

    --------------------------

    Acquisition en continue :
    1-le thread attend (Thread "permanant")
    2-appuie sur un bouton (Interface utilisateur)
    while (stop != 1) {
    3-acquisition (Thread "permanant")
    4-traitement des données (Interface utilisateur)
    5-affichage des données (Interface utilisateur)
    }

    Récapitulatif :

    Temps acquisition < temps traitement des données + temps affichage des données

    Ce qu'il faudrait c'est intégrer tous le traitement des données et leur gestion dans le thread et on aurait :

    Temps acquisition + temps traitement des données > temps affichage des données ?

    Si je ne dis pas de bêtise, ceci est plus juste.

    Je me pose juste la question de savoir si je peux intégrer toute ma gestion des données au sein du thread ! -> L'objet de l'interface utilisateur serait la que pour afficher les données et ne traiterait pas les données

Discussions similaires

  1. [JFreeChart] Gérer l'état du zoom initial
    Par javax_b dans le forum 2D
    Réponses: 9
    Dernier message: 08/06/2011, 00h58
  2. [Etat] Comment gérer des états concurrents (parallèles).
    Par Damien.Garrido dans le forum Design Patterns
    Réponses: 5
    Dernier message: 18/08/2008, 17h34
  3. [CR 9] Sous-états non exécutés
    Par zycomatic dans le forum SAP Crystal Reports
    Réponses: 5
    Dernier message: 11/06/2008, 09h16
  4. Gérer le temps d'exécution d'une requête.
    Par Soisy dans le forum Langage SQL
    Réponses: 2
    Dernier message: 25/09/2007, 09h06
  5. [ODBC] Gérer l'état de machines
    Par mohamed_ali dans le forum PHP & Base de données
    Réponses: 9
    Dernier message: 12/04/2007, 10h21

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