Je dois avoir juste un moment, car cela devrait être facile mais je n'arrive pas à le faire fonctionner correctement.Compteur atomique en gcc
Quelle est la bonne façon d'implémenter un compteur atomique dans GCC?
C'est-à-dire que je veux un compteur qui va de zéro à 4 et qui soit sûr pour les threads.
que je faisais ce (qui est encore enveloppé dans une classe, mais pas ici)
static volatile int _count = 0;
const int limit = 4;
int get_count(){
// Create a local copy of diskid
int save_count = __sync_fetch_and_add(&_count, 1);
if (save_count >= limit){
__sync_fetch_and_and(&_count, 0); // Set it back to zero
}
return save_count;
}
Mais il fonctionne de 1 à 1 à 4 inclus puis autour de zéro.
Il devrait aller de 0 à 3. Normalement, je ferais un compteur avec un opérateur de mod, mais je ne sais pas comment le faire en toute sécurité.
Peut-être que cette version est meilleure. Pouvez-vous voir des problèmes avec cela, ou offrir une meilleure solution.
int get_count(){
// Create a local copy of diskid
int save_count = _count;
if (save_count >= limit){
__sync_fetch_and_and(&_count, 0); // Set it back to zero
return 0;
}
return save_count;
}
En fait, je dois souligner qu'il n'est pas absolument essentiel que chaque thread obtienne une valeur différente. Si deux threads arrivaient à lire la même valeur en même temps, cela ne poserait pas de problème. Mais ils ne peuvent pas dépasser la limite à tout moment.
Si __sync_fetch_and_add "effectue une opération atomique par invocation" dépend du processeur - non spécifié dans la question. Il pourrait bien être implémenté selon votre approche compare-and-swap, qui est ce que j'ai utilisé sur le matériel Sun dans le passé (enfin, l'implémentation de mon ex-collègue, nommée "atomic_robin" :-)). –
Je ne parlais pas du nombre d'instructions exécutées; Il existe différentes manières d'implémenter exchange-add, mais elles sont toutes équivalentes tant qu'elles n'écrivent réellement en mémoire ("commit") qu'une seule fois. Le fait est que vous ne pouvez pas construire de "grandes" primitives atomiques parmi plusieurs petites; ils ne composent pas. Vous pouvez utiliser plusieurs étapes, mais l'étape finale (validation) doit être une opération atomique unique qui rend tout visible. S'il y a plus d'une telle étape à la fin, vous avez automatiquement une condition de compétition. –
Salut merci. C'est exactement ce que je cherche. Je ne sais pas tout à fait ce que je pensais avec ma deuxième solution. Je suppose que c'était le manque de sommeil qui m'a fait écrire un si bon code. – Matt