Comment implémenter un incrément atomique d'un pointeur sur un entier en utilisant C ++ 11 & lt; atomic & gt ;?
Alors que le portage de certaines Fenêtres de code C++ pour iOS, j'ai besoin de fournir une implémentation de Win32 l' long InterlockedIncrement(long *p)
appel. C'est assez facile en utilisant les fonctions définies dans <libkern/OSAtomic.h>
.
Cependant, je me demande si il est possible de l'écrire dans un OS de façon agnostique en utilisant juste le C++11 installations, principalement <atomic>
. Je suis venu avec, ce que je ne suis pas sûr accomplit ce que je veux:
inline long InterlockedIncrement(long* p)
{
std::atomic<long&> atomicP(*p);
return ++atomicP;
}
Fait ce travail? Est-ce suffisant? Les deux lignes ne sont pas atomiques, mais l'incrément doit être atomique, qui est la clé ici.
Tous les exemples d'utilisation pour <atomic>
que j'ai trouvé sont différents, d'où une std::atomic<T>
est défini et utilisé directement. Ici, je veux utiliser une variable de type long que les appelants me passe par adresse. Je ne pouvais pas trouver un tel exemple.
Edit: Clang 3.2 (dans Xcode 4.x) ne peut pas compiler ++atomicP
avec le message d'erreur "ne peut pas incrémenter la valeur de type std::atomic<long&>
" (ni atomicP += 1
).
Quelle serait la bonne façon?
Modifier à nouveau: un pointeur de mise en œuvre compile...
inline long InterlockedIncrement(long* p)
{
std::atomic<long*> atomicP(p);
return ++(*atomicP);
}
Mais j'ai peur que cela ne fonctionne pas, puisque je n'ai pas d'incrément un type atomique, mais la valeur pointée par le pointeur, ce qui n'est pas atomique.
source d'informationauteur Jean-Denis Muys
Vous devez vous connecter pour publier un commentaire.
Votre exemple de mise en œuvre est la construction d'une nouvelle atomique à partir d'un pointeur à chaque fois. Ce n'est pas le but de l'utilisation de std::atomique, et je ne crois pas qu'il fonctionne, comment vous le souhaitez.
À ma connaissance, la seule façon de faire ce que vous voulez faire (supprimer la dépendance sur InterlockedIncrement dans une plate-forme indépendante) est de remplacer toutes les déclarations de variables que vous en appelant Win32 "interlock" appelle avec std::atomic versions. Ensuite, vous pouvez supprimer le contrefil des appels et l'utilisation régulière de la valeur sémantique de modifier la variable de manière atomique. C'est plus lisible (et plus maintenable à l'avenir), de toute façon.
Je comprends que vous souhaitez laisser existant (bien testé) code en place, mais je ne pense pas que vous pouvez dans votre cas.
Je crois que vous pourriez utiliser un
atomic_fetch_add
opération. Jetez un oeil à l'exemple ici.__atomic_add_fetch
GCC extensionDans GCC 4.8, la norme C++ de la bibliothèque implémente
std::atomic::operator++
avec le CCG intégré__atomic_add_fetch
de sorte que vous pourriez écrire:Je ne suis pas sûr pour le bruit, mais il semble y avoir certaines options comme
__c11_atomic_fetch_add
http://clang.llvm.org/docs/LanguageExtensions.htmlComme d'autres l'ont mentionné, l'argument
p
lui-même devrait êtrestd::atomic
pour vous d'utiliser uniquement de la bibliothèque standard méthodes: convertir le pointeur dans atomique n'aide pas parce que l'atomique pointeur n'agit que sur le pointeur, pas sur ce qu'il désigne.