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

Boost C++ Discussion :

smart_ptr : shared vs intrusive


Sujet :

Boost C++

  1. #21
    Membre chevronné
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Par défaut
    Citation Envoyé par bafman Voir le message
    sachant que j'ai de plus en plus de classes qui heritent de enable_shared_from_this
    Pourquoi tes classes doivent-elles hériter de enable_shared_from_this?

    Autrement dit : quel est le contrat que tes classes garantissent, et qui nécessite enable_shared_from_this?

  2. #22
    Membre chevronné
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    Je peux te donner un exemple dans mon code au boulot, mais je n'ai bien évidemment pas le droit d'en dire trop, ce qui risque de limiter les discussions, en particulier sur les mérites comparés des design alternatifs...
    Je vais essayer de pas te faire perdre ton boulot alors.

    (Sauf que justement si je montre que ton design est sous-optimal, ça prouve mon point... )

    Citation Envoyé par JolyLoic Voir le message
    Le principe de base était d'avoir pour l'utilisateur des objets dans des conteneurs, qu'il allait récupérer et manier comme bon lui semble. Par contre, pour des raisons d'optim, ces objets ne doivent pas exister en mémoire tant que l'utilisateur ne s'y intéresse pas, et doivent disparaître quand il ne s'y intéresse plus.
    Dès qu'il ne s'y intéresse plus? Ce n'est donc pas tout à fait un cache (ma première idée a été : mais c'est un cache!).

    Citation Envoyé par JolyLoic Voir le message
    On a donc l'équivalent moral d'une map<string, weak_ptr<T> > et quand l'utilisateur tente d'accèder à un objet, soit le weak_ptr est vivant, et on retourne un shared_ptr issue de ce dernier, soit il ne l'est pas, dans ce cas là on le crée à la volée à partir d'un fichier de configuration.
    Donc quand la fonction cliente en a fini avec un T, elle détruit son shared_ptr<T>, le T est désalloué, mais il reste l'élément dans la map avec le weak_ptr<T> déconnecté ("null").

    C'est voulu de garder cette trace de l'association en mémoire? Est-ce que cette association rompue comporte encore des informations utiles? Est-ce que cette entrée déconnectée va servir à optimiser la prochaine recherche du même objet, ou est-ce juste de la mémoire conservée inutilement?

    (Tu me dis si je suis trop indiscret.)

  3. #23
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Citation Envoyé par corrector Voir le message
    Donc quand la fonction cliente en a fini avec un T, elle détruit son shared_ptr<T>, le T est désalloué, mais il reste l'élément dans la map avec le weak_ptr<T> déconnecté ("null").

    C'est voulu de garder cette trace de l'association en mémoire? Est-ce que cette association rompue comporte encore des informations utiles? Est-ce que cette entrée déconnectée va servir à optimiser la prochaine recherche du même objet, ou est-ce juste de la mémoire conservée inutilement?
    Oui, c'est voulu. Ce qui est voulu, c'est qu'il reste une entrée dans la map portant le bon nom, que cette entrée est visible lors d'un parcours de la map, et que si l'utilisateur veut accéder à l'objet à nouveau, il le peut. Le déchargement dynamique est totalement transparent pour lui, il n'est même pas au courant qu'il existe.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  4. #24
    Membre chevronné
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    Oui, c'est voulu. Ce qui est voulu, c'est qu'il reste une entrée dans la map portant le bon nom, que cette entrée est visible lors d'un parcours de la map, et que si l'utilisateur veut accéder à l'objet à nouveau, il le peut. Le déchargement dynamique est totalement transparent pour lui, il n'est même pas au courant qu'il existe.
    Autrement dit, l'utilisateur n'a pas accès à la map.

  5. #25
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Il a accès à quelquechose qui de son point de vue ressemble à une map<string, shared_ptr<T> >, mais en interne ressemble à une map<string, weak_ptr<T> > avec une instanciation automatique transparente à la demande.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  6. #26
    Membre chevronné
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Par défaut
    Citation Envoyé par Matthieu Brucher Voir le message
    Tu as un graphe de pointeurs, l'un pointant vers un autre, un cercle, quoi.
    Je comprends : x contient un shared_ptr vers y, y contient un shared_ptr vers x.

    Autrement-dit x possède y, y possède x. Donc par transitivité x possède x! C'est absurde, quelque chose ne peut pas se posséder lui-même dans une gestion automatique des ressources.
    Citation Envoyé par Matthieu Brucher Voir le message
    Si tu as un pointeur extérieur vers un pointeur appartenant au cercle et que tu le supprimes, tu t'attends à supprimer le cercle en entier.
    Non, pas vraiment. Si une instance se possède elle-même, c'est en réalité qu'on fait de la gestion manuelle des ressources. Alors mieux vaut écrire "delete this;" que "me.reset();" (préférer ce qui est strait forward).

    Dans le cadre d'une gestion automatique des ressources, basée sur des relations entre objets, relations matérialisées par des objets possédant (unique_ptr, shared_ptr, auto_ptr, etc.), relations correspondant au besoin effectif qu'a l'objet a d'avoir accès à l'objet b (a dépend de b, a possède b), l'auto-possession n'a aucun sens, elle est tautologique et triviale : tout objet a besoin de ses variables membre, introduire un objet possédant pour le matérialiser est absurde.
    Citation Envoyé par Matthieu Brucher Voir le message
    Si tu n'as pas de weak_ptr dans le cercle pointant vers ce même pointeur, ça ne marchera pas.
    Je ne comprends toujours pas ce que les weak_ptr vont y faire.

    Supposons : j'ai mon graphe de pointeurs, l'un pointant vers un autre, un cercle, quoi. Je fais quoi, concrètement, en C++?

  7. #27
    Membre chevronné
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Par défaut
    Citation Envoyé par bafman Voir le message
    Et puis, dernierement, j'ai decouvert l'existence des intrusive_ptr (ou plutôt, j'ai enfin compris comment ils fonctionnaient ).
    Comment tu as fais? Pas en lisant la doc je pense?

    Tu peux nous expliquer ce que fait enable_shared_from_this, et en quoi c'est une bonne solution à quel problème?

    Citation Envoyé par bafman Voir le message
    certe, l'utilisation des intrusive_ptr obligent à avoir un ref count et des fonctions en plus, mais du coup, on a plus besoin d'heriter de enable_shared_from_this quand on veut passer un pointeur this à un autre objet.
    Le plus gros problème que je voit à cette approche est l'augmentation de la taille de la classe, ce qui n'est pas forcement idéale dans le cas de petites classes (mais alors vraiment très petite ), et d'ailleurs, cet aventage est perdu si je doit heriter de enable_shared_from_this...
    Avant de passer aux micro-optimisations, il faudrait préciser les contraintes imposées aux classes. (D'ailleurs, dans boost, enable_shared_from_this contient un weak_ptr qui contient deux pointeurs, donc c'est plus gros qu'un compteur de référence.)

    Citation Envoyé par bafman Voir le message
    bref, le sujet du jour est :
    - les shared_ptr c'est naze ?
    - les intrusive_ptr c'est le mal ?
    La question est mal posée, évidemment. Ce qu'il faut que tu décides, c'est si toutes les instances de ta classe doivent être allouées dynamiquement, et être gérées par un système de smart pointer donné. (Il faut penser en terme de besoins et pas de composants standards.)

  8. #28
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Citation Envoyé par corrector Voir le message
    Je comprends : x contient un shared_ptr vers y, y contient un shared_ptr vers x.

    Autrement-dit x possède y, y possède x. Donc par transitivité x possède x! C'est absurde, quelque chose ne peut pas se posséder lui-même dans une gestion automatique des ressources.
    D'où l'intérêt des weak_ptr............

  9. #29
    Membre chevronné
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Par défaut std::enable_shared_from_this
    Toujours à propos de enable_shared_from_this, voici quelque chose de savoureux :
    Citation Envoyé par N2315, 20.6.6.4/14 [util.smartptr.enab]
    The shared_ptr constructors that create unique pointers can detect the presence of an enable_shared_from_this base and assign the newly created shared_ptr to its __weak_this member. —end note ]
    Et comment pourrait-il le faire? La classe de base enable_shared_from_this peut être inaccessible ou bien ambigüe (ou les deux). Par définition, il n'est pas possible de tester si une classe de base est inaccessible ou ambigüe.

  10. #30
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    C'est pour cela qu'il vaut mieux toujours dériver de manière public de enable_shared_from_this.

  11. #31
    Membre chevronné
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Par défaut
    Citation Envoyé par Matthieu Brucher Voir le message
    D'où l'intérêt des weak_ptr............
    Justement, je ne vois pas. Voila exactement ce que je comprends :

    Si on a graphe avec un cycle, et qu'on retire suffisamment d'arêtes, on peut obtenir un graphe sans cycle.

    Comme ici on discute de C++, pas de théorie des graphes, et que le résultat ci-dessus est en plus assez trivial, je déduis que ce n'est pas ça que tu cherches à m'expliquer.

    Quand tu me dis que weak_ptr suffit à résoudre le problème, tu pourrais aussi bien me dire qu'il suffit de voter pour le Parti de la Méditation Transcendantale (au fait, ils se présentent au municipales?) pour résoudre un problème de gestion de ressources en C++, ça me ferais le même effet : c'est possible qu'ils aient la solution au problème, mais je ne sais pas quelle est cette solution.

    Le problème dont il est question ne peut pas être : comment éviter d'avoir "x contient un shared_ptr vers y, y contient un shared_ptr vers x". Pour ne pas avoir cette situation, il faut (et il suffit) de ne pas provoquer la situation où "x contient un shared_ptr vers y, y contient un shared_ptr vers x".

    Chercher la solution de "x contient un shared_ptr vers y, y contient un shared_ptr vers x", c'est pour moi comme se demander si la phrase "La vache doit me touche de la jeudi" comporte une faute d'accord, où si tu préfère, comme poser la question : si x = 1/0, x \in R, quelle est valeur de x?

    Il doit y avoir un problème de C++, qui doit être de la forme "comment faire quelque chose en C++", pas "pourquoi mon programme qui n'utilise pas weak_ptr ne marche pas?", ni "est-ce qu'un programme qui utilise weak_ptr peut ne pas avoir une caractéristique qu'a un programme "semblable" qui n'utilise pas weak_ptr?".

  12. #32
    Membre chevronné
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Par défaut enable_shared_from_this
    Citation Envoyé par Matthieu Brucher Voir le message
    C'est pour cela qu'il vaut mieux toujours dériver de manière public de enable_shared_from_this.
    Si c'est requis quelque part, je ne l'ai pas vu. Si ça ne l'est pas, l'implémentation doit faire fonctionner :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class B;
    class A : enable_shared_from_this<B> {};
    class B : A, enable_shared_from_this<B> {};
     
    shared_ptr<B> p (new B);

  13. #33
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Citation Envoyé par corrector Voir le message
    Justement, je ne vois pas. Voila exactement ce que je comprends :

    Si on a graphe avec un cycle, et qu'on retire suffisamment d'arêtes, on peut obtenir un graphe sans cycle.

    Comme ici on discute de C++, pas de théorie des graphes, et que le résultat ci-dessus est en plus assez trivial, je déduis que ce n'est pas ça que tu cherches à m'expliquer.
    Le weak_ptr, ce sont les arêtes que tu supprimes, mais dont tu as tout de même besoin.
    Si tu dois parcourir le graphe pour supprimer à la main les éléments, il te faudra un garbage collector, donc ça ne marche pas.

    Est-ce que tu as regardé les liens donnés sur la page des smart_ptr ? En particulier celui-ci http://boost.org/libs/smart_ptr/smart_ptr.htm ?

  14. #34
    Membre chevronné
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Par défaut
    Citation Envoyé par Matthieu Brucher Voir le message
    Est-ce que tu as regardé les liens donnés sur la page des smart_ptr ?
    "la page des smart_ptr" => je ne vois de quelle page il s'agit

    Citation Envoyé par Matthieu Brucher Voir le message
    Il y a pas mal de liens sur cette page. Je crois avoir parcouru les pages de boost sur les smart_ptr, mais j'ai pu manquer quelque chose. Peux-tu m'orienter sur la bonne page?

  15. #35
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Tout en bas, les références, ils parlent des weak_ptr

  16. #36
    Membre chevronné
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Par défaut
    Citation Envoyé par Matthieu Brucher Voir le message
    Tout en bas, les références, ils parlent des weak_ptr
    Ceci : "[E&D-94] John R. Ellis & David L. Detlefs, Safe, Efficient Garbage Collection for C++, Usenix Proceedings, February, 1994. This paper includes an extensive discussion of weak pointers and an extensive bibliography"?

    Bon, ça ne va parler de boost::weak_ptr (weak_ptr.hpp : (c) 2001, 2002, 2003 Peter Dimov), mais ça peut être intéressant.

    Par rapport à boost :
    Citation Envoyé par Safe, Efficient Garbage Collection for C++, 3.4. Smart pointers
    In sum, smart pointers are actually rather dumb.
    Assez ironique de la part de boost de citer ça.

    Citation Envoyé par Safe, Efficient Garbage Collection for C++, 2.2. Coexistence
    In particular, objects in the non-collected heap should be able to point at objects in the collected heap, and vice versa.
    That is, a pointer of type T* should be able to reference an object of type T allocated in either heap.
    [...]
    These constraints preclude extensions to the type system identifying which pointers reference collected objects. Such extensions would require existing libraries to be modified and would effectively prevent libraries from manipulating both collected and non-collected objects.
    Tout le contraire des "smart pointers", donc.

    C'est passablement obsolète, par endroit :
    Citation Envoyé par Safe, Efficient Garbage Collection for C++, 3.4. Smart pointers
    Given class T derived from S, a smart pointer to T can't be assigned to a smart pointer to S.
    (Les templates membres ne devaient pas exister à l'époque?)

    Il est me semble t-il évident, bien que je ne le lise explicitement nul part, qu'on parle d'un gc pur jus, qui gère les cycles de pointeurs.

    D'ailleurs, en cherchant "cycle", la première occurrence est :
    Citation Envoyé par Safe, Efficient Garbage Collection for C++, 5.1. Object clean-up
    If A and B have non-empty destructors and each is reachable from the other (that is, they form a cycle), neither will be cleaned up or collected.
    [...]
    In our design, cycles of objects with clean-up functions will never be collected or cleaned-up.
    Donc à contrario, les cycles d'objets sans "clean-up functions" vont être collectés, c'est en tous cas ce que je comprends.

    Donc le cas de pointeurs cycliques que tu décris est géré automatiquement par ce système, il n'y a aucun besoin d'utiliser des "weak pointers".

Discussions similaires

  1. [VB.NET][C#] Equivalence Shared
    Par MALAGASY dans le forum Windows Forms
    Réponses: 7
    Dernier message: 10/01/2005, 12h12
  2. Share memory
    Par beLz dans le forum C
    Réponses: 5
    Dernier message: 21/12/2004, 00h50
  3. [Oracle 8i][Internet] Shared Pool Size
    Par dupin40 dans le forum Administration
    Réponses: 39
    Dernier message: 04/11/2004, 12h39
  4. [CR] variables shared
    Par rkampf dans le forum Formules
    Réponses: 4
    Dernier message: 08/04/2004, 19h28
  5. Réponses: 2
    Dernier message: 05/02/2004, 13h58

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