当前位置:首页 > C > 正文

C语言CAS操作详解(手把手教你实现Compare-and-Swap原子操作)

在多线程编程中,保证数据的一致性和线程安全是至关重要的。C语言CAS操作(Compare-and-Swap)是一种常见的原子操作技术,用于实现无锁并发控制。本文将从零开始,详细讲解如何在C语言中使用和实现CAS操作,即使你是编程小白,也能轻松理解。

什么是CAS操作?

CAS(Compare-and-Swap)是一种硬件级别的原子指令,用于比较内存中的值与预期值是否相等。如果相等,则将新值写入;否则不做任何操作。整个过程是原子的,不会被其他线程打断。

CAS操作通常用于实现无锁数据结构(如无锁队列、栈等),避免使用互斥锁带来的性能开销和死锁风险。

C语言CAS操作详解(手把手教你实现Compare-and-Swap原子操作) C语言CAS操作 CAS原子操作 compare-and-swap C语言并发编程 第1张

C语言中如何使用CAS?

现代C编译器(如GCC)提供了内置函数来实现CAS操作。最常用的是__atomic_compare_exchange_n或较老的__sync_bool_compare_and_swap

使用 GCC 内建函数实现 CAS

以下是一个简单的例子,演示如何使用__sync_bool_compare_and_swap实现一个自旋锁:

#include <stdio.h>#include <pthread.h>volatile int lock = 0; // 0 表示未锁定,1 表示已锁定void acquire_lock() {    while (__sync_bool_compare_and_swap(&lock, 0, 1) == 0) {        // 自旋等待,直到成功获取锁    }}void release_lock() {    __sync_bool_compare_and_swap(&lock, 1, 0);}// 测试函数void* thread_func(void* arg) {    acquire_lock();    printf("Thread %ld acquired the lock!\n", (long)arg);    // 模拟临界区操作    release_lock();    return NULL;}int main() {    pthread_t t1, t2;    pthread_create(&t1, NULL, thread_func, (void*)1);    pthread_create(&t2, NULL, thread_func, (void*)2);    pthread_join(t1, NULL);    pthread_join(t2, NULL);    return 0;}

上面的代码中,__sync_bool_compare_and_swap(&lock, 0, 1)会检查lock是否为0,如果是,则将其设为1,并返回true;否则返回false。这样就能实现一个简单的自旋锁。

更现代的方式:使用 C11 原子操作

C11标准引入了<stdatomic.h>头文件,提供了一套标准化的原子操作接口。这比依赖编译器内建函数更具可移植性。

#include <stdio.h>#include <stdatomic.h>#include <pthread.h>atomic_int lock = ATOMIC_VAR_INIT(0);void acquire_lock() {    int expected;    do {        expected = 0;    } while (!atomic_compare_exchange_weak(&lock, &expected, 1));}void release_lock() {    atomic_store(&lock, 0);}// 其余代码与上例类似...

这里使用了atomic_compare_exchange_weak,它是C11标准中的CAS函数。它接受一个指向期望值的指针,如果当前值等于期望值,则替换为新值;否则将当前值写入期望值变量中。

CAS操作的优缺点

  • 优点:无锁、高并发性能好、避免死锁。
  • 缺点:在高竞争场景下可能导致“活锁”(线程不断重试但始终失败);ABA问题(值从A变到B再变回A,CAS误判为未变)。

总结

通过本教程,你已经掌握了C语言CAS操作的基本原理和实现方式。无论是使用GCC内建函数还是C11标准原子库,你都可以在自己的项目中安全地实现无锁并发逻辑。

记住,C语言CAS操作是高性能并发编程的重要工具,掌握CAS原子操作能让你写出更高效、更安全的多线程程序。同时,了解compare-and-swap机制也有助于深入理解现代CPU的内存模型。如果你正在学习C语言并发编程,那么CAS操作是你必须掌握的核心技能之一。

希望这篇教程对你有所帮助!动手试试吧,实践是最好的老师。