Pattern compare-and-swap (CAS)
Implementi aggiornamenti lock-free con compare_exchange_weak e compare_exchange_strong
Pattern compare-and-swap (CAS) è una lezione C++ Academy gratuita su CoddyKit. Questa è la lezione 2 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento C++ Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso C++ Academy include 4 lezioni in totale.
La primitiva CAS
Confronto e scambio legge, confronta e scrive condizionatamente in modo atomico. È la base della maggior parte degli algoritmi lock-free.
Compare exchange in C++
Due varianti in std::atomic:
compare_exchange_strong(expected, desired)— ha successo quando il valore corrente è uguale a expectedcompare_exchange_weak(expected, desired)— può fallire falsamente
Struttura di un ciclo CAS
Il ciclo CAS classico: leggere, calcolare, tentare la scrittura. Riprovare se un altro thread ha vinto la contesa.
std::atomic<int> a{0};
int old = a.load();
int next;
do {
next = compute_new(old);
} while (!a.compare_exchange_weak(old, next));CAS per un aggiornamento atomico
Utilizzare CAS quando il nuovo valore dipende da quello precedente. Un semplice store perderebbe gli aggiornamenti dei thread concorrenti.
// Atomic max
int current = a.load();
while (newval > current && !a.compare_exchange_weak(current, newval));Stack lock-free: push
Una semplice operazione push su uno stack lock-free utilizza CAS per inserire un nuovo nodo in testa.
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));
}Fallimento spurio
compare_exchange_weak può fallire anche quando i valori coincidono, ad esempio su piattaforme come ARM, dove l'istruzione sottostante può fallire. Utilizzarlo all'interno dei cicli; utilizzare strong quando riprovare è costoso.
Schema di aggiornamento: reset
Reimpostare un valore a uno stato noto solo se non è stato modificato.
int expected = 42;
if (a.compare_exchange_strong(expected, 0)) {
// a was 42 and is now 0
}Elemento costitutivo: contatore atomico
Per un semplice contatore, fetch_add è più semplice e veloce di un ciclo CAS.
Elemento costitutivo: flag atomico
Per un semplice flag booleano, std::atomic_flag è più leggero di std::atomic<bool> e supporta test_and_set.
Ragionare sulla concorrenza
Il codice lock-free è notoriamente difficile da analizzare. Utilizzare test rigorosi, come TSan e il fuzzing, modelli formali quando disponibili e preferire implementazioni già collaudate.
Quando scegliere CAS
Utilizzare CAS quando:
- Più thread aggiornano frequentemente lo stesso valore
- I mutex mostrano la contesa come collo di bottiglia
- La sezione critica è molto breve e semplice
Quando non utilizzare CAS
Evitare CAS quando:
- L'aggiornamento richiede più di un paio di operazioni
- La correttezza è più importante del throughput
- Il team non dispone di esperienza nella programmazione lock-free
Verifica rapida
Perché in genere utilizziamo compare_exchange_weak all'interno di un ciclo?
Riepilogo
Il confronto e scambio aggiorna atomicamente un valore solo se è uguale a un valore previsto. I cicli CAS gestiscono gli aggiornamenti concorrenti senza lock. Utilizzare compare_exchange_weak nei cicli e strong per i tentativi singoli.
Domande Frequenti
La lezione «Pattern compare-and-swap (CAS)» è gratuita?
Sì — il testo completo di «Pattern compare-and-swap (CAS)» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso C++ Academy, passa a CoddyKit PRO. Il corso C++ Academy include 4 lezioni in totale.
Cosa imparerò in «Pattern compare-and-swap (CAS)»?
Implementi aggiornamenti lock-free con compare_exchange_weak e compare_exchange_strong Eserciti C++ Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare C++ Academy?
Non è richiesta alcuna esperienza precedente. C++ Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.
Quanto tempo richiede la lezione «Pattern compare-and-swap (CAS)»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione C++ Academy?
Sì. Ogni lezione C++ Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- std::atomic e memory order
- Pattern compare-and-swap (CAS)
- Implementazione di una coda lock-free
- Hazard pointer e problema ABA