Atomique pointeurs en c++ et les objets de passage entre les threads
Ma question implique std::atomique et les données que ce pointeur pointe. Si dans le thread 1 j'ai
Object A;
std:atomic<Object*> ptr;
int bar = 2;
A.foo = 4; //foo is an int;
ptr.store(*A);
et si dans le thread 2 j'observe que ptr points à Un, puis-je être assuré de la ptr->foo est de 4 bar 2? La mémoire par défaut pour le modèle atomique de pointeur (de manière Séquentielle cohérente) de garantir que les travaux sur la non atomique (dans ce cas, A. foo) qui se produisent avant atomique magasin sera vu par les autres threads avant qu'il voit la cession de la même atomique.magasin pour les deux cas?
Si ça aide ou des questions, je suis à l'aide x64 (et je ne se soucient cette plate-forme), gcc (avec une version qui prend en charge atomics).
Je pense que tu veux dire
Connexes: C++11 introduit un standardisés modèle de mémoire. Ça veut dire quoi? Et comment est-ce que ça va affecter la programmation en C++?
ptr.store(&A)
? ptr.store(*A)
n'a pas de sens (sauf si Object
définit Object * Object::operator*();
...).Connexes: C++11 introduit un standardisés modèle de mémoire. Ça veut dire quoi? Et comment est-ce que ça va affecter la programmation en C++?
OriginalL'auteur Michael | 2014-11-06
Vous devez vous connecter pour publier un commentaire.
La réponse est oui, et peut-être pas
Le modèle de mémoire principes:
C++11 atomics utilisation par défaut la
std::memory_order_seq_cst
de la mémoire de la commande, ce qui signifie que les opérations sont séquentiellement cohérente.Sur le plan sémantique, c'est que la commande de l'ensemble des opérations est comme si toutes ces opérations ont été effectuées de manière séquentielle :
C++ standard de l'article 29.3/3 explique comment cela fonctionne pour atomics: "Il y aura un seul total de la commande S sur tous les memory_order_seq_cst opérations, en cohérence avec la “passe avant” de l'ordre et de la modification des commandes pour tous les endroits touchés, de sorte que chaque memory_order_seq_cst
opération qui se charge d'une valeur constate soit la dernière modification selon cet ordre S, ou le résultat d'une opération qui n'est pas memory_order_seq_cst."
La section 1.10/5 explique comment cela impacte aussi des non-atomics: "La bibliothèque définit un certain nombre d'opérations atomiques (...) qui sont spécialement identifiés comme les opérations de synchronisation. Ces opérations jouent un rôle dans l'élaboration des affectations en un seul fil visible à l'autre."
La réponse à votre question est oui !
Risque de non-atomiques
Vous ne devez cependant être conscient que, en réalité, la cohérence de la garantie est plus limité pour les non-valeurs atomiques.
Supposons une première exécution du scénario:
Ici,
i
est 4. Parce queptr
est atomique, le fil (2) en toute sécurité obtient la valeur&A
lorsqu'il lit le pointeur. La mémoire de la commande s'assure que tous les travaux effectués AVANTptr
sont vus par les autres threads ("passe avant" contrainte).Mais supposons qu'une seconde d'exécution du scénario:
Ici, le résultat est indéfini. Il pourrait être de 4 à cause de la mémoire de commande de la garantie que ce qui se passe avant la
ptr
assignement est vu par les autres threads. Mais rien n'empêche les affectations effectuées par la suite d'être vu ainsi. Ainsi, il pourrait être 8.Si vous avez eu
*ptr = 8;
au lieu deA.foo=8;
ensuite, vous avez la certitude de nouveau:i
serait 8.Vous pouvez le vérifier expérimentalement avec ceci par exemple:
Conclusions
Pour conclure, la réponse à votre question est oui, mais seulement si aucun autre changement de la non atomique données qui se passe après la synchronisation. Le principal risque est que seulement
ptr
est atomique. Mais cela ne s'applique pas aux valeurs souligné.À noter que, en particulier des pointeurs apporter davantage de synchronisation de risque lorsque vous réaffectez le atomique pointeur vers un non atomique pointeur.
Exemple:
OriginalL'auteur Christophe
Par défaut, C++-11 atomique des opérations d'acquisition/diffusion de la sémantique.
Donc un thread que de voir votre magasin verrez également toutes les opérations effectuées avant elle.
Vous pouvez trouver plus de détails ici.
std::memory_order_seq_cst
, qui a même plus de garanties que de l'acquisition/diffusion, mais en effet c'est tout ce qui serait nécessaire ici de toute façon.)OriginalL'auteur David Schwartz