Compare-and-swap: CAS-mönster
Implementera låsfria uppdateringar med compare_exchange_weak och compare_exchange_strong
Compare-and-swap: CAS-mönster är en gratis lektion i C++ Academy på CoddyKit. Detta är lektion 2 av 4. Du kan läsa vilka 3 lektioner som helst i den här lärvägen kostnadsfritt i sin helhet – därefter låser CoddyKit PRO upp alla lektioner, plus praktisk övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Den ingår i lärvägen för C++ Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i C++ Academy innehåller totalt 4 lektioner.
CAS-primitiven
Compare-and-swap läser, jämför och skriver villkorligt på ett atomiskt sätt. Grunden för de flesta låsfria algoritmer.
C++ compare exchange
Två varianter i std::atomic:
compare_exchange_strong(expected, desired)— lyckas när det aktuella värdet är lika med expectedcompare_exchange_weak(expected, desired)— kan misslyckas falskt
En CAS-loops uppbyggnad
Den klassiska CAS-loopen: läs, beräkna, försök skriva. Försök igen om en annan tråd vann kapplöpningen.
std::atomic<int> a{0};
int old = a.load();
int next;
do {
next = compute_new(old);
} while (!a.compare_exchange_weak(old, next));CAS för atomisk uppdatering
Använd CAS när det nya värdet beror på det gamla. En vanlig store skulle förlora uppdateringar från samtidiga trådar.
// Atomic max
int current = a.load();
while (newval > current && !a.compare_exchange_weak(current, newval));Låsfri stack: push
En enkel push-operation på en låsfri stack använder CAS för att installera en ny nod längst fram.
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));
}Falskt misslyckande
compare_exchange_weak kan misslyckas även när värdena stämmer överens — på plattformar som ARM, där den underliggande instruktionen får misslyckas. Använd den i loopar och använd strong när det är dyrt att försöka igen.
Uppdateringsmönster: återställning
Återställ ett värde till ett känt tillstånd endast om det inte har ändrats.
int expected = 42;
if (a.compare_exchange_strong(expected, 0)) {
// a was 42 and is now 0
}Byggblock: atomisk räknare
För en vanlig räknare är fetch_add enklare och snabbare än en CAS-loop.
Byggblock: atomisk flagga
För en enkel boolesk flagga är std::atomic_flag lättare än std::atomic<bool> och stöder test_and_set.
Resonera kring samtidighet
Låsfri kod är berömt svår att resonera kring. Använd rigorösa tester (TSan, fuzzing), formella modeller när sådana finns och föredra befintliga, vältestade implementationer.
När CAS bör väljas
Använd CAS när:
- flera trådar ofta uppdaterar samma värde
- mutexar orsakar flaskhalsar på grund av konkurrens
- den kritiska sektionen är mycket kort och enkel
När CAS inte bör användas
Undvik CAS när:
- uppdateringen kräver mer än ett par operationer
- korrekthet är viktigare än genomströmning
- teamet saknar expertis inom låsfri programmering
Snabb kontroll
Varför använder vi vanligtvis compare_exchange_weak i en loop?
Sammanfattning
Compare-and-swap uppdaterar atomiskt ett värde endast om det är lika med ett förväntat värde. CAS-loopar hanterar samtidiga uppdateringar utan lås. Använd compare_exchange_weak i loopar och strong för engångsförsök.
Lär dig C++ med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 51
- Lektioner
- 203
Vanliga frågor
Är lektionen ”Compare-and-swap: CAS-mönster” gratis?
Ja – du kan läsa vilka 3 lektioner som helst i lärvägen C++ Academy, inklusive ”Compare-and-swap: CAS-mönster”, kostnadsfritt i sin helhet här på webben. Därefter låser CoddyKit PRO upp alla lektioner, plus interaktiv övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Kursen i C++ Academy innehåller totalt 4 lektioner.
Vad lär jag mig i ”Compare-and-swap: CAS-mönster”?
Implementera låsfria uppdateringar med compare_exchange_weak och compare_exchange_strong Ni övar på C++ Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig C++ Academy?
Du behöver inga förkunskaper. Utbildningen i C++ Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 2 av 4.
Hur lång tid tar lektionen ”Compare-and-swap: CAS-mönster”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här C++ Academy-lektionen?
Ja. Varje C++ Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- std::atomic och minnesordningar
- Compare-and-swap: CAS-mönster
- Implementera en låsfri kö
- Hazard pointers och ABA-problemet