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 :

delete Thread


Sujet :

Multithreading

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 18
    Par défaut delete Thread
    Bonjour, j'ai commencé à programmer il y a pas longtemps en Qt.

    J'utilise un QThread dans un programme qui lance un fichier exterieur.Le programme marche.Mais quand tout est fini et que je veux delete mon QThread j ai droit à un bon crash, pourtant j'attend que tout soit finit(thread et le process)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    test=new Lancem(this,cas); //Création de mon Thread
    spy=new QSignalSpy(test, SIGNAL(finished())); //je surveille si il a fini
     
    ...
    ...
     
    while(spy->count()==0)
    {
          QTest::qWait(250);
    }
    m_pTexB->append(QString("%1").arg(test->isFinished()));
    delete test;
    Je veux faire un delete car sinon chaque fois que je vais lancer un QThread je vais comsommer de la memoire vive pour rien.

    Merci d'avance(en esperant que ma question soit pas trop stupide )

  2. #2
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Par défaut
    salut,

    si j'ai bien compris, la fonction dans laquelle tu fais le 'delete' est en fait un slot, lui-même appelé par un signal du QThread.

    Si c'est le cas, c'est la raison pour laquelle tu as un crash: ton slot (appelons-le mySlot() ) a été appelé en interne par une fonction de QThread (appelons la 'callSlot()'). Or lorsque ton mySlot() retourne, la pile d'exécution retombe dans le code de callSlot(), fonction membre du QThread qui vient d'être détruit. => Crash.

    La solution est de ne pas faire un delete immédiatement mais de le programmer pour un tout petit peu plus tard, le temps que ta pile d'exécution sorte de callSlot(). Une fonction existe pour cela dans la classe QObject (dont dérivent toutes les classes Qt qui ont des signaux/slots) : QObject::deleteLater().

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 18
    Par défaut
    Pour la premiere reponse en fait je veux faire un delete avant, je peux pas me permettre le delete du parent vu comme j'ai programmé.

    J ai compris ce que tu viens d'expliquer. Mais le slot ne fait pas parti du QThread.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    connect(test, SIGNAL(exitmess(bool)),this, SLOT(Lancementdel(bool)));
    j'emet un signal quand je quitte, et c'est le parent qui récupere et lance un slot à lui. Donc ton explication marche pas ici(enfin je crois).

    En fait je vais essayer ta fonction deleteLater()

  4. #4
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Par défaut
    Citation Envoyé par Keldran Voir le message
    j'emet un signal quand je quitte, et c'est le parent qui récupere et lance un slot à lui. Donc ton explication marche pas ici(enfin je crois).
    Mon assomption sur ton organisation signaux / slots était erronnée, mais le principe reste le même à partir du moment ou dans la chaîne de connexion de signaux / slots qui a amené à exécuter le slot du 'delete' il y a un signal ou un slot qui appartient à l'objet que tu veux détruire.

    Par exemple, le cas s'applique si tu as:
    - un objet QThread qui émet le signal 'tartampion'
    - ce signal est récupéré par un QMonObjet dans son slot 'onTartampion'.
    - le slot 'onTartampion' fais un delete sur l'objet 'monAutreObj'
    - un slot 'onMonAutreObjDetruit', connecté au signal 'monAutreObj::destroyed' est activé
    - 'onMonAutreObjDetruit' fait un delete du QThread.

    On voit ici que 'onMonAutreObjDetruit' ne fait pas partie de QThread, pourtant dans la pile d'exécution on a une suite d'appels successifs qui lient QThread à onMonAutreObjDetruit qui fait le delete :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    QThread::tartampion 
      => QMonObjet::onTartampion 
        => delete monAutreObj
          => monAutreObj::destroyed 
            => onMonAutreObjDetruit 
              => delete QThread

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 18
    Par défaut
    Pour info j'avais testé et je crois que c est faux. Si tu delete le parent en 1er puis le fils ca plante.

    deleteLater() regle le probleme, merci

    En meme temps que je suis la,est ce normal quand je delete QThread je recupere pas toute la memoire vive avant sa création?

  6. #6
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Par défaut
    Citation Envoyé par Keldran Voir le message
    Pour info j'avais testé et je crois que c est faux. Si tu delete le parent en 1er puis le fils ca plante.
    Dans ce sens là (delete parent puis enfant), ça plante car tu essaie de faire un delete sur un pointeur qui pointe vers une zone mémoire déjà libérée, on est d'accord.

    Mais ce qu'avançait Gulish n'était pas la même chose, il parlait de détruire d'abord l'enfant puis le parent:
    Si tu declares un parent à ton QThread, le parent, lorsqu il va etre fermé, va détruire tous "ses enfants". Or, si tu as deja détruis un de ces enfants, il va tenter de détruire "un pointeur null", et donc crash.

  7. #7
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Par défaut
    Pour en revenir au sujet:

    Citation Envoyé par Keldran Voir le message
    En meme temps que je suis la,est ce normal quand je delete QThread je recupere pas toute la memoire vive avant sa création?
    Pour moi quatre causes potentielles:

    1- soit la mémoire est effectivement libérée, mais tu ne le 'vois' pas (ou pas tout de suite) dans ta mesure de delta de mémoire vive.

    2- soit Qt utilise un système de mémoire cache (ou autre) pour une raison x ou y pour une partie des informations et donc il ne libère pas cette partie de la mémoire en même temps que le thread est déleté (peu probable à priori)

    3- soit tu as une fuite de mémoire provenant de ton code.

    4- soit il y a une fuite de mémoire dans le code de Qt.


    D'où les quatre solutions (respectives) à envisager:

    1- n'oublie pas que le deleteLater ne fait pas le 'delete' immédiatement, mais à la prochaine exécution de la boucle d'événements. Essaie donc de calculer le delta de mémoire dispo un peu plus tard si ce n'est déjà pas le cas.

    2- inspecter le code source de Qt pour y déceler un tel mécanisme, mais franchement j'y crois moyen moins.

    3- L'idée serait de faire le calcul de delta non pas sur un seul thread créé/détruit mais sur la même opération répétée un grand nombre de fois (plusieurs centaines) pour voir si le delta augmente proportionnellement. Si c'est le cas, on est typiquement devant une fuite mémoire. Un outil pour détecter ce genre de chose pourrait t'être utile (genre ValGrind).

    4- achète un ticket de loto, tu as plus de chances de toucher le gros lot

  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
    J'ajouterai que si t'es sous windows,
    le gestionnaire de tache n'est pas très précis.
    Attention à l'interprétation

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 18
    Par défaut
    Ouai c est bizarre.Je sais pas comment ils gerent la memoire vive. En fait je lance une liste de programme, desfois la memoire utilisée à la fin ne bouge pas même en attendant un peu et desfois elle diminue beaucoup des qu il a fini la list. Je pense pas avoir de fuite ,enfin j espere. En tout cas merci

  10. #10
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Par défaut
    Une idée comme ça (qui n'est qu'une pure hypothèse de ma part, à vérifier): le système d'exploitation alloue de la mémoire vive aux processus par bloc (page mémoire ?) entier ; il ne la déclare donc comme à nouveau libre que par bloc également et peut-être par un mécanisme asynchrone qui s'exécute "quand le système a du temps libre".

    D'où les libérations par gros blocs et pas toujours juste après que le delete ait été exécuté.

Discussions similaires

  1. Tri multi-threadé
    Par Tifauv' dans le forum C
    Réponses: 8
    Dernier message: 28/06/2007, 09h00
  2. [Kylix] Pb de Thread !!
    Par Anonymous dans le forum EDI
    Réponses: 1
    Dernier message: 25/04/2002, 13h53

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