0Pricing
C++ Academy · Lezione

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

  1. std::atomic e memory order
  2. Pattern compare-and-swap (CAS)
  3. Implementazione di una coda lock-free
  4. Hazard pointer e problema ABA
← Torna a C++ Academy