#include stdatomic.h在C11标准中原子操作通过stdatomic.h头文件提供支持这使得编写无锁lock-free并发代码更为便捷。下面为你介绍原子操作的基本用法和常见场景。原子类型的定义C11 引入了多种原子类型像atomic_int、atomic_ptr等。你既可以使用标准类型名称也能借助_Atomic类型说明符来定义原子类型。#include stdatomic.h atomic_int counter; //使用标准原子类型名称 _Atomic(int) another_counter; //使用_Atomic说明符 atomic_ptr(int) ptr; //原子指针原子操作函数针对原子类型C11提供了一套标准函数这些函数具备内存顺序memory order参数能够对内存同步语义加以控制。基础操作//初始化 atomic_init(counter, 0); //把counter初始化为0 //读取操作 int value atomic_load(counter); //原子性地读取counter的值 //写入操作 atomic_store(counter, 42); //原子性地将42写入counter //读取-修改-写入操作 int old atomic_fetch_add(counter, 1); //原子性地让counter加1并返回旧值 int new atomic_add_fetch(counter, 1); //原子性地让counter加1并返回新值比较并交换操作CASint expected 0; _Bool success atomic_compare_exchange_strong ( counter, //目标原子变量 expected, //期望值如果counter等于此值就进行交换 100 //新值当比较成功时使用 ); //要是比较成功counter会被设为100同时返回true //若比较失败expected会被更新为counter的当前值返回false内存顺序内存顺序参数能够对原子操作的内存同步语义进行控制主要有以下几种memory_order_relaxed仅保证操作的原子性不进行内存同步。memory_order_acquire用于加载操作可阻止后续的内存访问被重排到该操作之前。memory_order_release用于存储操作能防止之前的内存访问被重排到该操作之后。memory_order_seq_cst默认选项提供顺序一致性确保所有线程看到的操作顺序相同。//以relaxed内存顺序执行原子递增操作 atomic_fetch_add_explicit(counter, 1, memory_order_relaxed); //使用release-acquire语义实现同步 atomic_store_explicit(flag, 1, memory_order_release); //写入flag //... 等待其他线程 ... int value atomic_load_explicit(flag, memory_order_acquire); //读取flag //此时能保证在写入flag之前的所有内存操作对读取flag之后的代码都是可见的实际应用示例下面是一个使用原子操作实现无锁计数器的示例#include stdatomic.h #include threads.h #include stdio.h atomic_int counter 0; int increment(void* arg) { for (int i 0; i 100000; i) { atomic_fetch_add(counter, 1); //原子性递增 } return 0; } int main() { thrd_t t1, t2; //创建两个线程 thrd_create(t1, increment, NULL); thrd_create(t2, increment, NULL); //等待线程结束 thrd_join(t1, NULL); thrd_join(t2, NULL); //输出结果应为200000 printf(Counter value: %d\n, atomic_load(counter)); return 0; }注意要点原子性范围原子操作仅保证单个变量的原子性若要对多个变量进行原子操作需借助锁机制。内存顺序选择在性能关键的场景中应避免使用默认的memory_order_seq_cst可选用更宽松的内存顺序像memory_order_relaxed。平台支持大部分现代处理器都对原子操作提供硬件支持但在一些特殊平台上原子操作可能会回退到使用锁。通过运用 C11 的原子操作能够编写高效且安全的并发代码不过这需要对内存模型有深入的理解。