Je lis http://gcc.gnu.org/onlinedocs/libstdc++/manual/shared_ptr.html et certains problèmes de sécurité des threads ne sont toujours pas clairs pour moi:
- Standard garantit que le comptage de références est géré thread-safe et qu'il est indépendant de la plateforme, non?
- Problème similaire - la norme garantit qu'un seul thread (contenant la dernière référence) appellera delete sur un objet partagé, non?
- shared_ptr ne garantit aucune sécurité de thread pour les objets qui y sont stockés?
ÉDITER:
Pseudo code:
// Thread I
shared_ptr<A> a (new A (1));
// Thread II
shared_ptr<A> b (a);
// Thread III
shared_ptr<A> c (a);
// Thread IV
shared_ptr<A> d (a);
d.reset (new A (10));
L'appel de reset () dans le thread IV supprimera l'instance précédente de la classe A créée dans le premier thread et la remplacera par une nouvelle instance? De plus, après avoir appelé reset () dans le thread IV, les autres threads ne verront que l'objet nouvellement créé?
c++
c++11
shared-ptr
Dingo
la source
la source
make_shared
place denew
Réponses:
Comme d'autres l'ont souligné, vous l'avez bien compris en ce qui concerne vos 3 questions d'origine.
Mais la dernière partie de votre modification
est incorrect. Seulement
d
pointera vers le nouveauA(10)
, eta
,b
etc
continuera à le point à l'originalA(1)
. Cela peut être clairement vu dans le court exemple suivant.(De toute évidence, je ne me suis pas dérangé avec le filetage: cela ne tient pas compte du
shared_ptr::reset()
comportement.)La sortie de ce code est
la source
Correct,
shared_ptr
s utilise des incréments / décréments atomiques d'une valeur de comptage de référence.La norme garantit qu'un seul thread appellera l'opérateur de suppression sur un objet partagé. Je ne suis pas sûr qu'il spécifie spécifiquement le dernier thread qui supprime sa copie du pointeur partagé sera celui qui appelle delete (ce serait probablement le cas en pratique).
Non, ils ne le font pas, l'objet qui y est stocké peut être modifié simultanément par plusieurs threads.
EDIT: Léger suivi, si vous voulez avoir une idée du fonctionnement des pointeurs partagés en général, vous voudrez peut-être consulter la
boost::shared_ptr
source: http://www.boost.org/doc/libs/1_37_0/boost/shared_ptr.hpp .la source
std::shared_ptr
n'est pas thread-safe.Un pointeur partagé est une paire de deux pointeurs, un vers l'objet et un vers un bloc de contrôle (tenant le compteur de référence, des liens vers des pointeurs faibles ...).
Il peut y avoir plusieurs std :: shared_ptr et chaque fois qu'ils accèdent au bloc de contrôle pour changer le compteur de référence, il est thread-safe mais
std::shared_ptr
lui-même n'est PAS thread-safe ou atomique.Si vous affectez un nouvel objet à un
std::shared_ptr
moment où un autre thread l'utilise, il peut se retrouver avec le nouveau pointeur d'objet mais toujours en utilisant un pointeur vers le bloc de contrôle de l'ancien objet => CRASH.la source
std::shared_ptr
instance n'est pas thread-safe. De la référence std :: shared_ptr:If multiple threads of execution access the same shared_ptr without synchronization and any of those accesses uses a non-const member function of shared_ptr then a data race will occur;
std::shared_ptr<T>
instance est garantie thread-safe lorsqu'elle est toujours utilisée par valeur (copiée / déplacée) à travers les limites de thread. Toutes les autres utilisationsstd::shared_ptr<T>&
sont dangereuses au