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

C++ Discussion :

Liberation de memoire désyncronisee


Sujet :

C++

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    98
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 98
    Par défaut Liberation de memoire désyncronisee
    Salut !

    Bon comme tout le monde il me semble je remarque que le multi thread est en train de prendre un énorme souffle et tout le monde s'y met !!!

    Je ne voudrais donc pas etre en reste et comme je n'ai pas de connaissance dans ce domaine je me prend à imaginer de tres simples utilisations du multithread.

    J'aimerais faire une chose tres simple à imaginer mais qui s'avere devenir assez complexe au vu des discussion tres techniques sur ce sujet.

    J'aimerais désyncroniser la libération mémoire. Dans l'objectif d'une application temp réelle j'ai donc quelques fonctions qui s'apelle tres tres souvent et qui crée de grosses quantités de donnees valables uniquement sur un appel. S'il était possible j'aimerais bien qu'en plus de ca elles n'aient pas à perdre du temps sur la destruction ( la destruction ne représente pas un simple delete ).

    Mon idée est donc tout simplement de créer un thread à qui on passerait l'objet à détruire et qu'on lacherai ensuite dans la nature en espèrant qu'il fera son travail et qu'il s'auto détruira des sa fin.

    Voila je vous remercie d'avances de vos conseils et réponses

    @++
    Seb

    ps : je souhaiterais en plus de ca utiliser boost.

  2. #2
    Membre Expert
    Avatar de Patriarch24
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2003
    Messages
    1 047
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2003
    Messages : 1 047
    Par défaut
    Tu n'es pas obligé de créer un thread à chaque fois (c'est très coûteux) ! Il suffit d'en créer un, qui boucle sur une liste que tu remplis avec les objets à détruire.
    Pour optimiser le temps d'exécution du thread (pour éviter qu'il boucle pour rien), ajoute des conditions qui te permettront d'endormir le thread si la liste est vide, et de le réveiller si quelqu'un la remplit. Avec boost, c'est ultra simple !

    Bon courage.

  3. #3
    Membre expérimenté
    Inscrit en
    Décembre 2003
    Messages
    272
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 272
    Par défaut
    Ca ne justifie pas vraiment un thread pour ça, il suffit de changer ton allocateur/désallocateur pour qu'ils tiennent à jour une liste des libérations mémoire à faire. A la fin, tu vides ce qu'il reste dans la liste.

    Ou encore tu utilise un allocateur "pool".

    [...]grosses quantités de donnees valables uniquement sur un appel.
    Tu veux dire que tu pourrais utiliser les variables automatiques ?

  4. #4
    Membre émérite Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Par défaut
    De plus, ce que je ferais si j'était toi, c'est de mettre le thread de désallocation en priorité basse (en tout cas en dessous de normal) pour eviter de ralentir le thread principal en cas d'exécution sur une machine mono-processeur.

    Et encore, il y aurait quantité d'autre choses à dire sur ton pb.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    98
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 98
    Par défaut
    Oula je ne pensais pas que c'était un sujet aussi vaste que ca

    Bilan des bonnes choses que je vais retenir en tenant compte de mon niveau et de mes besoins :
    1 - Creation d'un unique thread chargé de la destruction totale niarg niarg (effectivement ca me coutera bien moins cher)
    2 - Priorité basse : oui justement c'est exactement ma perspective => faire les désallocations des qu'on a le temps uniquement.
    3 - Avec boost c'est tres simple => heuu sauf peut-etre quand on s'en sort pas avec la doc qui il faut le dire est extremement claire pour quelqu'un qui n'en a jamais fait ^o)

    Quand aux variables automatiques ??? ^o) What's that ????? mais peut-etre trop ambitieu pour moi donc pas besoin d'infos pour le moment.

    Donc ma question est : tout ce qui a été proposé je veu bien mais : "Comment ?"
    Deuxiemement pour info la structure que je dois detruire est un gros vector de pointeur.. donc à parcourir si je ne m'abuse ....

    Merci d'avance de toutes vos réponses
    @+
    Seb

  6. #6
    Membre émérite Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Par défaut
    Le thread doit avoir un pointeur initialement à NULL.

    Quand tu n'as plus besoin de ton tableau, tu passe le pointeur sur son adresse au thread qui va le stocker. Ensuite tu reveilles le thread.
    L'exécution continue pendant que le thread va faire un delete quand il aura le temps :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void thread_boucle_principale() {
      while (true) {
         // Je met le thread en sommeil
         ...
         // Le thread se réveille (par un signal par exemple),
         //   mais les instructions vont s'exécuter à son rythme
         if (vector_ptr != NULL) {
           delete vector_ptr;
           vector_ptr = NULL;
         }
      }
    }
    La syntaxe peut varier lors de l'utilisation de boost, mais l'idée est là.

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    98
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 98
    Par défaut
    Ok Merci beaucoup mchk0123 je commence doucement à comprendre le principe

    Par contre maintenant j'ai quelques petites questions ....

    pourquoi lorsque j'apelle la methode sleep de la classe thread mon thread continue de courrir ?

    Comment détruirais-je mon thread ??? parceque while( true ) :p

    Pour mettre un thread en priorité basse dans boost comment faut-il faire ?

    Merci d'avance
    @+
    Seb

  8. #8
    Membre émérite Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Par défaut
    Normalement tu ne devrait pas avoir besoin de sleep().

    Ton problème peut être résolu simplement en utilisant un mécanisme dit "Inter Process Communication" (en fait inter-thread).

    Pour avoir jeté un oeil au tuto suivant : http://miles.developpez.com/tutoriel...hread/#LII-B-7, boost gère les signaux au sein de la classe
    condition : ici :
    http://www.boost.org/doc/html/condition.html

    Pour la sortie du while, un simple booléen en lecture / écriture publique, avec un break si mis à vrai, devrait faire l'affaire.

  9. #9
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 394
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 394
    Par défaut
    Avec un seul pointeur partagé, il risque d'y avoir des soucis.
    Ce que je conseillerais, c'est un buffer circulaire et deux sémaphores qui vont avec : Un modèle producteur/consommateur éprouvé, et aucune allocation ou désallocation du coté du thread producteur.

    Ainsi, le thread de désallocation fait le nettoyage quand il a le temps...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  10. #10
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Pour du multi-threadé en temps réel il faut pas des algorithmes wait-free ?

  11. #11
    Expert confirmé
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 526
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 526
    Par défaut
    Citation Envoyé par Sébastien P
    Salut !

    Bon comme tout le monde il me semble je remarque que le multi thread est en train de prendre un énorme souffle et tout le monde s'y met !!!

    Je ne voudrais donc pas etre en reste et comme je n'ai pas de connaissance dans ce domaine je me prend à imaginer de tres simples utilisations du multithread.

    .
    je crois qu'il ya une grosse confusion ; la programmation multiprocessus cela existe depuis des années avec les systèmes multitaches comme Unix et les CPU qui le permettent..
    avec Windows c'est apparu sous Windows95 et NT.
    Ne pas utiliser ces techniques à tort et à travers

    Citation Envoyé par Sébastien P
    Ok Merci beaucoup mchk0123 je commence doucement à comprendre le principe

    pourquoi lorsque j'apelle la methode sleep de la classe thread mon thread continue de courrir ?
    Seb
    Le thread continue à tourner parce que l'OS lui alloue toujours un espace temps pour l'exécution ; au niveau de l'OS il y a toujours un PID ou Program Identification....

  12. #12
    Membre émérite Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Par défaut
    Citation Envoyé par Mat.M
    Le thread continue à tourner parce que l'OS lui alloue toujours un espace temps pour l'exécution ; au niveau de l'OS il y a toujours un PID ou Program Identification....
    Pour Mat.M, je crois qu'il y a confusion, aussi bien durant un sleep(), qu'en attente d'un wait, ou bien une opération sychrone bloquante, le thread est provisoirement stoppé ; c'est à dire qu'il n'execute plus aucun code.
    Le thread est mis dans un état "idle", qui à pour effet d'avoir une utilisation du CPU de 0%. Ce qui correspond bien à la notion de thread stoppé.

    Pour Sébastien P, je ne comprends donc pas comment tu en est arrivé à la conclusion que ton thread court toujours ? Le temps d'un sleep(), le thread n'exécute rien du tout et ne consomme aucune CPU puisque qu'aucune instruction n'est envoyée au CPU.

  13. #13
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    98
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 98
    Par défaut
    Je parlais du sleep en tant que la methode de la classe thread de boost ...... pas du Sleep de windows.h

    Enfin j'ai plus ou moins réusii à faire ce que je voulais il me semble....

    En pseudo code ca donnerais (j'ai pas mon code réel sous la main) :

    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
     
    class LiberateurAssyncrone {
        private :
             static Fifo<void*> listeDatas;
             static boost::mutex semaphore;
             static boost::thread* thread_pointer;
     
        public  :
             static void Init();
             static void Step();
             static void ThreadMain();
             static void AddDatas( void* data );
    };
     
    Fifo<void*> LiberateurAssyncrone::listeDatas;
    boost::mutex LiberateurAssyncrone::semaphore;
    boost::thread* LiberateurAssyncrone::thread_pointer;
     
    void LiberateurAssyncrone::Init() {
          lock(mutex);
          thread_pointer = new boost::thread( LiberateurAssyncrone::ThreadMain );
          unlock(mutex);
    }
     
    void LiberateurAssyncrone::ThreadMain() {
          while( true ) {
              Sleep( temporisation );
              Step();
          }
    }
     
    void LiberateurAssyncrone::Step() {
          lock(mutex);
          if( ! fifo.Vide() ) {
             for( int i=0; i<nbDeleteMax; i++ ) {
                free( fifo.Pop() );
             }
          }
          unlock(mutex);
    }
     
    void LiberateurAssyncrone::AddDatas( void* data ) {
        lock(mutex);
        fifo.Push( data );
        unlock(mutex);
    }
    voila c'est du "En gros" hein
    Et j'ai donc maintenant quelques nouvelles questions : comment puis-je faire pour regler la priorité du thread sans avoir à utiliser ce vilain Sleep()

    Si je fais un free( ) et que mes donnees sont des objets .... je pense que les destructeurs ne seront pas appelés ... ^o) et même si ce ne sont que des int qui ont été créé par un new est-ce que free( est valable ????

    Voila merci encore et d'avance
    @+
    Seb

  14. #14
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 394
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 394
    Par défaut
    Sous Windows, on change la priorité d'un thread avec SetThreadPriority().
    Mais j'ignore s'il existe un moyen portable...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  15. #15
    Membre émérite Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Par défaut
    Citation Envoyé par Sébastien P
    Je parlais du sleep en tant que la methode de la classe thread de boost ...... pas du Sleep de windows.h
    Vraiment bizarre que la fonction sleep() de boost ne mettent pas le thread dans un état "idle".

    Citation Envoyé par Sébastien P
    Si je fais un free( ) et que mes donnees sont des objets .... je pense que les destructeurs ne seront pas appelés ... ^o) et même si ce ne sont que des int qui ont été créé par un new est-ce que free( est valable ????
    Seb
    Il y a 2 choses à avoir en tête :
    - free() appellé sur un pointeur d'instance de classe n'appellera jamais le destructeur (déjà là ça craint), mais en plus si tes instances sont allouées avec "new" le comportement du "free()" est indéterminé, et au mieux tu auras un crash de ton programme. Donc à fuire au maximum.
    - utiliser delete & new peuvent trés bien s'appliquer à des int (comme à des tableaux de int). Dans ce cas là tout ce passe comme si on faisait un simple malloc() (mais au moins new & delete sont utilisés en tandem)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #include <cstdio>
    #include <iostream>
     
    using namespace std;
     
    int main() {
      int *ptr;
     
      ptr = new int(123);
      cout << "Valeur de ptr : " << *ptr << endl;
      delete ptr;
     
      return 0;
    }
    Pour ton implémentation, là encore, 2 choix possibles :
    - soit tu fait dériver tes classes à détruire d'une classe abstraite ancêtre commune (attention à bien mettre tous les destructeurs en "virtual")
    - soit tu rend ta classe LiberateurAsynchrone "template"
    (dans ce cas il te faudra choisir entre 1 seul pool de désallocation ou n pool, chaque pool étant dédié à un type d'objets)

    Voilà, voilou.

  16. #16
    Membre émérite Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Par défaut
    Voilà ce que dit la documentation de boost à propos de la méthode "thread::sleep()" :

    Citation Envoyé par Documentation boost::thread
    static void sleep(const xtime& xt);
    Effects: The current thread of execution blocks until xt is reached.
    Ce que j'en pense, c'est qu'elle fonctionne identiquement à un classique Sleep() de l'API Win32.

  17. #17
    Membre expérimenté
    Inscrit en
    Décembre 2003
    Messages
    272
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 272
    Par défaut
    Citation Envoyé par mchk0123
    Ce que j'en pense, c'est qu'elle fonctionne identiquement à un classique Sleep() de l'API Win32.
    Un petit coup d'oeil aux sources pousse vers cette idée aussi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void thread::sleep(const xtime& xt)
    {
        for (int foo=0; foo < 5; ++foo)
        {
    #if defined(BOOST_HAS_WINTHREADS)
            int milliseconds;
            to_duration(xt, milliseconds);
            Sleep(milliseconds);
    ...
    Bon il reste à vérifier d'où sort BOOST_HAS_WINTHREADS, et éventuellement à comprendre à quoi sert la boucle.

  18. #18
    Membre émérite Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Par défaut
    Citation Envoyé par Ulmo
    [/code]Bon il reste à vérifier d'où sort BOOST_HAS_WINTHREADS, et éventuellement à comprendre à quoi sert la boucle.
    Ouais bien vu !

    Je penses que "BOOST_HAS_WINTHREADS" veut dire à la fois "je suis sur plateforme Windows" (ne pas oublier que Boost est multi-OS) et "sur cette plateforme les threads Windows existent" (par exemple ils pourraient manquer sur Windows CE (ce que je doute) ou sur d'autres Windows).

    @Ulmo : Je vais abuser, mais étant donné que je n'ai pas d'installation de Boost sous la main, tu pourrais faire un cherche sur boost::thread.h pour voir s'il existe une fonction Low Level similaire à "SetThreadPriority()" ?
    Sebastien P. t'en remercie par avance .

  19. #19
    Expert confirmé
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 526
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 526
    Par défaut
    Citation Envoyé par mchk0123
    Pour Mat.M, je crois qu'il y a confusion, aussi bien durant un sleep(), qu'en attente d'un wait, ou bien une opération sychrone bloquante, le thread est provisoirement stoppé ; c'est à dire qu'il n'execute plus aucun code.
    .
    Non monsieur il n'y pas de confusion :aucun code n'est exécuté effectivement mais au niveau de l'OS le thread est toujours existant....

  20. #20
    Membre émérite Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Par défaut
    Citation Envoyé par Mat.M
    Non monsieur il n'y pas de confusion :aucun code n'est exécuté effectivement mais au niveau de l'OS le thread est toujours existant....
    Entièrement d'accord avec vous Monsieur², c'est plutôt :

    Citation Envoyé par Mat.M
    Le thread continue à tourner parce que l'OS lui alloue toujours un espace temps pour l'exécution
    Qui me fait réagir : je doute que les OS multi-activitées attribuent une plage d'exécution aux threads qui sont en état "idle".

Discussions similaires

  1. Liberer la memoire
    Par Renardo dans le forum Access
    Réponses: 13
    Dernier message: 15/05/2006, 11h33
  2. liberation de memoire necessaire ?
    Par firejocker dans le forum C
    Réponses: 14
    Dernier message: 09/05/2006, 17h14
  3. Liberation de memoire
    Par dede92 dans le forum C
    Réponses: 17
    Dernier message: 18/03/2006, 21h31
  4. liberer la memoire
    Par jopab04 dans le forum Langage
    Réponses: 14
    Dernier message: 11/02/2006, 15h56
  5. liberation de memoire d une fenetre modale
    Par ienien dans le forum MFC
    Réponses: 6
    Dernier message: 04/01/2006, 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