Schémas de comparaison-échange CAS
Implémenter des mises à jour sans verrou avec compare_exchange_weak et compare_exchange_strong
Schémas de comparaison-échange CAS est une leçon C++ Academy gratuite sur CoddyKit. Ceci est la leçon 2 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage C++ Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours C++ Academy comprend 4 leçons au total.
La primitive CAS
La comparaison-échange lit, compare et écrit conditionnellement de manière atomique. C’est le fondement de la plupart des algorithmes sans verrou.
Comparaison-échange en C++
Deux variantes dans std::atomic :
compare_exchange_strong(expected, desired)— réussit lorsque la valeur actuelle est égale à la valeur attenduecompare_exchange_weak(expected, desired)— peut échouer à tort
Anatomie d’une boucle CAS
La boucle CAS classique : lire, calculer, tenter d’écrire. Réessayez si un autre thread a remporté la course.
std::atomic<int> a{0};
int old = a.load();
int next;
do {
next = compute_new(old);
} while (!a.compare_exchange_weak(old, next));CAS pour une mise à jour atomique
Utilisez CAS lorsque la nouvelle valeur dépend de l’ancienne. Un simple store ferait perdre les mises à jour des threads concurrents.
// Atomic max
int current = a.load();
while (newval > current && !a.compare_exchange_weak(current, newval));Empilement sans verrou
Une opération push simple sur une pile sans verrou utilise CAS pour installer un nouveau nœud en tête.
struct Node { int value; Node* next; };
std::atomic<Node*> head{nullptr};
void push(int v) {
Node* n = new Node{v, nullptr};
n->next = head.load();
while (!head.compare_exchange_weak(n->next, n));
}Échec intempestif
compare_exchange_weak peut échouer même lorsque les valeurs correspondent, sur des plateformes comme ARM où l’instruction sous-jacente est autorisée à échouer. Utilisez-le dans les boucles ; utilisez strong lorsque réessayer est coûteux.
Modèle de mise à jour : réinitialisation
Réinitialisez une valeur à un état connu uniquement si elle n’a pas changé.
int expected = 42;
if (a.compare_exchange_strong(expected, 0)) {
// a was 42 and is now 0
}Composant de base : compteur atomique
Pour un compteur simple, fetch_add est plus simple et plus rapide qu’une boucle CAS.
Composant de base : indicateur atomique
Pour un simple indicateur booléen, std::atomic_flag est plus léger que std::atomic<bool> et prend en charge test_and_set.
Raisonner sur la concurrence
Le code sans verrou est réputé très difficile à analyser. Utilisez des tests rigoureux (TSan, tests aléatoires), des modèles formels lorsqu’ils sont disponibles et préférez des implémentations existantes éprouvées.
Quand choisir CAS
Utilisez CAS lorsque :
- Plusieurs threads mettent fréquemment à jour la même valeur
- Les verrous mutex révèlent une contention qui constitue un goulot d’étranglement
- La section critique est très courte et simple
Quand ne pas utiliser CAS
Évitez CAS lorsque :
- La mise à jour nécessite plus de quelques opérations
- La correction est plus importante que le débit
- L’équipe ne possède pas l’expertise nécessaire en programmation sans verrou
Vérification rapide
Pourquoi utilise-t-on généralement compare_exchange_weak dans une boucle ?
Récapitulatif
La comparaison-échange met à jour une valeur de manière atomique uniquement si celle-ci est égale à la valeur attendue. Les boucles CAS gèrent les mises à jour concurrentes sans verrous. Utilisez compare_exchange_weak dans les boucles et strong pour les tentatives uniques.
Questions Fréquemment Posées
La leçon « Schémas de comparaison-échange CAS » est-elle gratuite ?
Oui — le texte complet de « Schémas de comparaison-échange CAS » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours C++ Academy, passe à CoddyKit PRO. Le cours C++ Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Schémas de comparaison-échange CAS » ?
Implémenter des mises à jour sans verrou avec compare_exchange_weak et compare_exchange_strong Tu pratiques C++ Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer C++ Academy ?
Aucune expérience préalable n'est requise. C++ Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 2 sur 4.
Combien de temps prend la leçon « Schémas de comparaison-échange CAS » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon C++ Academy ?
Oui. Chaque leçon C++ Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- std::atomic et ordres mémoire
- Schémas de comparaison-échange CAS
- Implémenter une file sans verrou
- Pointeurs de danger et problème ABA