รูปแบบ Compare-and-Swap (CAS)
สร้างการอัปเดตแบบไร้ล็อกด้วย compare_exchange_weak และ compare_exchange_strong
รูปแบบ Compare-and-Swap (CAS) เป็นบทเรียน C++ Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C++ Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C++ Academy มีบทเรียนทั้งหมด 4 บทเรียน
องค์ประกอบพื้นฐาน CAS
การเปรียบเทียบและแลกเปลี่ยนค่า จะอ่าน เปรียบเทียบ และเขียนตามเงื่อนไขแบบอะตอมิก เป็นพื้นฐานของอัลกอริทึมแบบไม่ใช้ล็อกส่วนใหญ่
การเปรียบเทียบและแลกเปลี่ยค่าใน C++
มีสองรูปแบบใน std::atomic:
compare_exchange_strong(expected, desired)— สำเร็จเมื่อค่าปัจจุบันเท่ากับ expectedcompare_exchange_weak(expected, desired)— อาจล้มเหลวโดยไม่มีเหตุผลที่แท้จริง
โครงสร้างของลูป CAS
ลูป CAS แบบคลาสสิก: อ่าน คำนวณ และพยายามเขียนใหม่ ให้ลองอีกครั้งหากเธรดอื่นชนะการแข่งขัน
std::atomic<int> a{0};
int old = a.load();
int next;
do {
next = compute_new(old);
} while (!a.compare_exchange_weak(old, next));ใช้ CAS สำหรับการอัปเดตแบบอะตอมิก
ใช้ CAS เมื่อค่าใหม่ขึ้นอยู่กับค่าเดิม การใช้ store โดยตรงอาจทำให้การอัปเดตจากเธรดที่ทำงานพร้อมกันสูญหาย
// Atomic max
int current = a.load();
while (newval > current && !a.compare_exchange_weak(current, newval));สแตกแบบไม่ใช้ล็อก: Push
การ push ลงสแตกแบบไม่ใช้ล็อกอย่างง่ายจะใช้ CAS เพื่อติดตั้งโหนดใหม่ไว้ที่ส่วนหัว
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));
}ความล้มเหลวแบบหลอก
compare_exchange_weak อาจล้มเหลวแม้ค่าจะตรงกัน ซึ่งเกิดได้บนแพลตฟอร์มอย่าง ARM ที่คำสั่งพื้นฐานอนุญาตให้ล้มเหลวได้ ใช้ภายในลูป และใช้ strong เมื่อการลองซ้ำมีต้นทุนสูง
รูปแบบการอัปเดต: การรีเซ็ต
รีเซ็ตค่าให้เป็นสถานะที่ทราบแน่ชัด เฉพาะเมื่อค่านั้นยังไม่เปลี่ยนแปลง
int expected = 42;
if (a.compare_exchange_strong(expected, 0)) {
// a was 42 and is now 0
}องค์ประกอบพื้นฐาน: อะตอมิก Counter
สำหรับตัวนับธรรมดา fetch_add เรียบง่ายและเร็วกว่าใช้ลูป CAS
องค์ประกอบพื้นฐาน: แฟล็กอะตอมิก
สำหรับแฟล็กบูลีนอย่างง่าย std::atomic_flag มีน้ำหนักเบากว่า std::atomic<bool> และรองรับ test_and_set
การให้เหตุผลเกี่ยวกับการทำงานพร้อมกัน
โค้ดแบบไม่ใช้ล็อกขึ้นชื่อว่าให้เหตุผลได้ยาก ใช้การทดสอบอย่างเข้มงวด เช่น TSan และการฟัซซิง ใช้แบบจำลองทางการเมื่อมีให้ใช้ และควรเลือกใช้การใช้งานที่ผ่านการทดสอบอย่างหนักแล้ว
เมื่อใดควรเลือกใช้ CAS
ใช้ CAS เมื่อ:
- มีหลายเธรดอัปเดตค่าเดียวกันบ่อยครั้ง
- มิวเท็กซ์แสดงการแย่งใช้เป็นคอขวด
- ส่วนวิกฤตสั้นและเรียบง่ายมาก
เมื่อใดไม่ควรใช้ CAS
หลีกเลี่ยง CAS เมื่อ:
- การอัปเดตต้องทำการดำเนินการมากกว่าสองสามรายการ
- ความถูกต้องสำคัญกว่าอัตราการประมวลผล
- ทีมขาดความเชี่ยวชาญด้านการเขียนโปรแกรมแบบไม่ใช้ล็อก
ตรวจสอบอย่างรวดเร็ว
เหตุใดโดยทั่วไปเราจึงใช้ compare_exchange_weak ภายในลูป
สรุปทบทวน
การเปรียบเทียบและแลกเปลี่ยค่าจะอัปเดตค่าแบบอะตอมิกก็ต่อเมื่อค่านั้นเท่ากับค่าที่คาดไว้ ลูป CAS จัดการการอัปเดตพร้อมกันได้โดยไม่ใช้ล็อก ใช้ compare_exchange_weak ภายในลูป และใช้ strong สำหรับการลองเพียงครั้งเดียว
คำถามที่พบบ่อย
บทเรียน “รูปแบบ Compare-and-Swap (CAS)” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “รูปแบบ Compare-and-Swap (CAS)” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C++ Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C++ Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “รูปแบบ Compare-and-Swap (CAS)”
สร้างการอัปเดตแบบไร้ล็อกด้วย compare_exchange_weak และ compare_exchange_strong คุณปฏิบัติ C++ Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C++ Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน C++ Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน
บทเรียน “รูปแบบ Compare-and-Swap (CAS)” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน C++ Academy นี้ได้ไหม
ได้ บทเรียน C++ Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- std::atomic และลำดับการจัดเรียงหน่วยความจำ
- รูปแบบ Compare-and-Swap (CAS)
- การสร้างคิวแบบไร้ล็อก
- พอยน์เตอร์ตรวจสอบอันตรายและปัญหา ABA