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 :

Plantage aléatoire en 3D


Sujet :

Multithreading

  1. #1
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2011
    Messages : 129
    Par défaut Plantage aléatoire en 3D
    Bonjour,

    Je viens vers vous à cause d'un problème que je n'arrive vraiment pas à régler après plusieurs jours. Je réalise le portage d'une application de
    Linux à Windows et c'est évidemment catastrophique.

    Voilà, j'ai donc mon programme principal qui réalise des affichages de cartes. J'ai donc deux boutons. le premier Crée un widget qui crée un Thread de calcul en se chargeant de l'affichage des données.
    Le deuxième bouton réalise un affichage 3D en créant un widget comportant un GLWidget. Séparément, les deux fonctionnent plutot bien, mais simultanément, l'application crash après un temps aléatoire.
    Lorsque les fenêtres sotn lancées seules, le programme plante sporadiquement, et évidemment, en mode debug, tout tourne comme sur des roulettes... :/

    J'ai tout de même relevé certains bugs parfois indiquant pour fichier, les dll utilisées (QtOpenGL4, QtGui, QtCore4, mingw10...).

    J'essaye donc de lever des exeptions dans une certaine classe : la classe de lecture des données (nécessaires pour l'affichage des cartes). mais il n'en est rien, aucune exception levée durant la lecture.

    Cette classe est passée en paramètre (pointeur) au widget3D (lorsque qu'on appuie sur un bouton) et au Thread (lancé par le widget appelé par l'autre bouton) réalisant l'affichage des cartes. J'ai un moment pensé que le problème pouvant être le partage de données, j'ai donc mis en place un mutex lorsque les deux widgets accèdent aux données pour être sur qu'il ne pouvait pas y avoir deux lectures/ecritures simultanées. En vain.

    J'ai crée des objets dynamiques de la classe qui soccupe de la lecture des données et dans laquelle les deux widgets viennent lire et écrire, le problème reste le même.

    Je m'y perds complètement et je ne comprends absolument pas d'ou ce problème peut venir. Mémoire ? accès de deux Threads différents à une même zone mémoire (malgré le mutex ) ?



    Voilà, je ne pense pas que ce soit utile de vous livrer du code ici,
    seulement mon message fait un peu brouillon, c'est assez complexe à
    expliquer, aussi je préfère que vous me posiez des questions ou me demandiez quel code vous souhaitez voir.

    J'attends plutot des informations quant au débug. J'ai lus l'article :

    http://alexandre-laurent.developpez....pplications/#L4-A-1
    mais j'avoue ne pas savoir quoi utiliser ni comment étant donné que le
    programme plante à des moments différents. (parfois, les deux widgets parviennent durant quelques secondes à lire les données l'un après l'autre avant que ca crash.)

    En éspérant que quelqu'un puisse me fournir une aide quelconque, tout idée est la bienvenue.

  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
    Citation Envoyé par 0_Azerty_0 Voir le message
    Voilà, je ne pense pas que ce soit utile de vous livrer du code ici,
    Ca aurai pu aider ^^

    Ton thread fait quoi exactement?

  3. #3
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2011
    Messages : 129
    Par défaut
    le Thread récupère les données dans la classe qui le les lit dans un fichier (appelons la Reader). Il les traite et fabrique une QImage.

    Via un Sender, il l'envoit au Widget qui affiche cette dernière. Cette partie là fonctionne à merveille toute seule.

    Je vais essayer de te fournir un peu de code.

  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 0_Azerty_0 Voir le message
    le Thread récupère les données dans la classe qui le les lit dans un fichier (appelons la Reader). Il les traite et fabrique une QImage.

    Via un Sender, il l'envoit au Widget qui affiche cette dernière. Cette partie là fonctionne à merveille toute seule.

    Je vais essayer de te fournir un peu de code.
    Ok. Tu ne fais donc pas d'appel IHM dans ton thread. Je pensais à cela.

    Peut tu montrer comment tu utilise tes mutex?

  5. #5
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2011
    Messages : 129
    Par défaut
    Tu ne fais donc pas d'appel IHM dans ton thread.
    Non aucun, je suis certain qu'il n'y a aucun problème de ce côté là, ca tourne de puis un moment. Les problèmes sont apparues lors du partage des ressources.

    Le Thread execute cette ligne qui lui permet de calculer les données nécessaires, puis les récupère :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    reader->safe_compute(2,current_date);
     
    // Mise à jour des données dépendantes de reader
    classes = reader->clone_classes();
    maxsat = reader->maxsat;
    brush = reader->brush; // recuperation de pointeur
    Dans le Reader :

    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
    /* Aiguille vers la bonne fonction compute tout en conservant une gestion des données protégée */
    void Reader::safe_compute(int dim, int date)
    {
        cout << "Processus "<< dim << "D entre pour la date N°" << date << endl;
     
        try {
     
            /* Vérouille le mutex si la 3D travaille sur this */
            mutex.lock();
                if(!computing)
                    computing = true;
                else
                {
                    waitcondition.wait(&mutex);
                    cout << "Processus "<< dim<< "D a fini d'attendre pour la date" << date << endl;
                }
            mutex.unlock();
     
            /* Compute */
            if(dim == 2)
                compute2d(date);
            else if (dim == 3)
                compute3d(date);
     
            cout << "Processus "<< dim<< "D travaille pour la date N°" << date << endl;
     
            /* Dévérouille le mutex */
            mutex.lock();
                computing = false;
                waitcondition.wakeAll();
            mutex.unlock();
        }
        catch (exception e)
        {
            cout << "Impossible de réaliser un compute des données pour la " << dim << "D a la date "<< date << endl;
        }
     
        cout << "Processus "<< dim<< "D libère le mutex" << endl;
    }
    L'exception du catch n'est absolument jamais levée

  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
    Pourquoi
    waitcondition.wait(&mutex); ?

    Sinon, regarde les mutexlocker :
    http://qt.developpez.com/faq/?page=m...anipuler-mutex

  7. #7
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2011
    Messages : 129
    Par défaut
    Le fait est que mes fonctions compute2d et compute3d réalisent une lecture/écriture dans les attributs de reader, la solution est-elle donc valable ?

  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 0_Azerty_0 Voir le message
    Le fait est que mes fonctions compute2d et compute3d réalisent une lecture/écriture dans les attributs de reader, la solution est-elle donc valable ?
    Dans le code que tu montre, elles ne sont pas protégées.

  9. #9
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2011
    Messages : 129
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Dans le code que tu montre, elles ne sont pas protégées.
    Qu'entends tu par protégées ? "Je pensais ce code sécurisé du fait que les ressources (d'après moi) ne pouvaient pas être accédées par deux objets en même temps.

    D'ailleurs, je n'ai pas précisé, mais étonnement, il n'arrive jamais qu'un Thread se retrouve en attente de l'autre.

    J'ai compris le concept QMutexLocker, c'est pratique, mais je vois difficilement comment le coupler avec mes waitconditions à vrai dire.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Pourquoi waitcondition.wait(&mutex); ?
    Parce qu'on m'a appris comme cela. Je commence à remettre en doute mes connaissances sur les mutex.

  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
    Pourquoi ce code ne suffit pas?

    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
    try {
            /* Vérouille le mutex si la 3D travaille sur this */
           QMutexLocker lock( &mutex);
     
            /* Compute */
            if(dim == 2)
                compute2d(date);
            else if (dim == 3)
                compute3d(date);
     
        }
        catch (exception e)
        {
            cout << "Impossible de réaliser un compute des données pour la " << dim << "D a la date "<< date << endl;
        }
    EN faite, j'ai l'impression que tu veux faire un mutex avec des waitconditions

    A ton avis, que se passe t'il lors du waitcondition.wakeAll(); dans la thread qui est bloqué à waitcondition.wait(&mutex); ?
    T1 est bloqué à waitcondition.wait(&mutex)
    T2 débloque T1 avec waitcondition.wakeAll()
    T1 est débloqué et appel Compute /!\ => computing == false
    T2 test computing, le met à true et appel Compute

    T1 et T2 appel Compute en concurrence => crash aléatoire.

  11. #11
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2011
    Messages : 129
    Par défaut
    EN faite, j'ai l'impression que tu veux faire un mutex avec des waitconditions
    J'aime bien les trucs compliqués


    En fait, je venais d'essayer ton bout de code juste avant que tu le postes !
    Rien n'y fait, toujours le même problème :/

    Ca survient la plus part du temps quand le Widget3D est démarré, juste après le GLWIdget->show();

    (En tout cas, merci, je suis tout de même content d'avoir découvert le MutexLocker !)

  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
    Pour localiser a peu prés où il y as le crash, vue que ce la crach n'est qu'en release, tu peux compiler en release avec des info debug.
    Ca ne te donnera pas la ligne mais ca peux te donner la fonction exacte.

    Si tu as du temps, essaie aussi de compiler avec visual studio( la version express est gratuite). Le fait de changer de compilateur fait souvent apparaître des erreurs mémoire cachées.

  13. #13
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2011
    Messages : 129
    Par défaut
    Bon et bien, merci beaucoup, je vais essayer ca, en attendant, je vais creuser encore un peu, et malheureusement, impossible d'installer quoi que ce soit sur cette machine...

    EDIT : Si jamais ca peut servir, QtCReator renvoit toujours cette erreur en plantant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MonProg.exe a quitté avec le code -1073741819
    j'ai cru comprendre que c'était du à une histoire de pointeur NULL. J'ai aucun pointeur NULL.

  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
    tu as peut être un pointeur non initialisé ou un pointeur que tu as détruit mais pas mis à zéro.

  15. #15
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2011
    Messages : 129
    Par défaut
    J'ai bien vérifié, mais le hic, c'est que de toute manière, le problème se produit en aucun cas lorsqu'un objet est détruit.

    Je lis des données et subitement, bim ca plante. J'essaye avec un seul processus le 2D, et ca plante également de temps à autre , parfois tout de suite, parfois pas, j'y comprends franchement rien :/ là.

    Dans tous les cas, je vois pas d'où un problème de pointeur nul pourrait venir. Je peux en plus rien installer ici, bref merci tout de même pour ton aide !

  16. #16
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2011
    Messages : 129
    Par défaut
    J'ai finis par avancer et régler quelques problèmes, mais ce n'est pas terminé (Mingw n'est vraiment pas indulgent) !

    J'ai remarqué qu'une fois mon GLWidget initialisé, la fonction PaintGL() est appellée une fois (c'est la callback qui soccupe de réaliser le rendu), le SwapBuffers semble s'être réalisé correctement, et l'application crash juste ensuite Entre deux appels de PaintGL()... Je vois pas commencer débugguer ca. Il me semble que tu as des connaissances OpenGL, tu sais si ca peut être une histoire de contexte ?

    Voici donc les fonctions responsables !

    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
    void GLWidget::paintGL()
    {
        glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);
     
        // Passage du tampon de profondeur en lecture seule
        glDepthMask (GL_FALSE);
     
        draw();
    }
     
    void GLWidget::draw()
    {
     
        glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
     
        m_cam->look();
     
        count_fps++;
     
        glPushMatrix();
        glEnable (GL_BLEND);
     
        // Rotation de la scene sur elle même.
        if(spinning)
            SpinIncrease();
     
        glRotatef(spin, 0.0, 0.0, 1.0);
     
     
        if(VBO == 1)
            m_map->draw_VBO();
        else
            m_map->draw();
     
        glDisable (GL_BLEND);
        glPopMatrix();
        glFlush();
     
        swapBuffers();
    }
    NB : Le fait de commenter le contenu intégral de ces deux fonctions ne corrige pas le problème... Si je réinitialise toutes mes données et que je lance ce code, il tourne quelques secondes avant de crasher..

    EDIT : Il semblerait qu'une partie du problème provienne de ce bug : https://bugreports.qt-project.org/browse/QTBUG-5462

Discussions similaires

  1. Plantages aléatoires en exécution et en dev
    Par lbrun79 dans le forum Access
    Réponses: 6
    Dernier message: 06/11/2007, 19h10
  2. Plantage aléatoire avec intellde
    Par arnaud_verlaine dans le forum Windows XP
    Réponses: 4
    Dernier message: 30/06/2007, 13h37
  3. [Access 2003] Plantage aléatoire
    Par Strontium dans le forum Access
    Réponses: 1
    Dernier message: 04/06/2007, 15h07
  4. Plantage aléatoire à l'ouv. de fichiers ext.
    Par Stutak dans le forum Access
    Réponses: 3
    Dernier message: 09/08/2006, 19h36
  5. Réponses: 15
    Dernier message: 07/07/2005, 11h05

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