0Pricing
C++ Academy · Leçon

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 attendue
  • compare_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

  1. std::atomic et ordres mémoire
  2. Schémas de comparaison-échange CAS
  3. Implémenter une file sans verrou
  4. Pointeurs de danger et problème ABA
← Retour à C++ Academy