原子操作
C11 引入标准原子操作 <stdatomic.h>,提供无锁的线程安全操作。原子操作保证操作不可中断,是多线程编程中避免数据竞争的基础。C11 定义了原子类型、原子操作函数和内存序控制。
基本原子类型
#include <stdatomic.h>
_Atomic int counter; /* 原子整数 */
atomic_int counter2; /* 等价 */
atomic_int count = ATOMIC_VAR_INIT(0); /* 初始化 */
原子操作
#include <stdatomic.h>
#include <stdio.h>
atomic_int counter = 0;
/* 原子增加 */
atomic_fetch_add(&counter, 1); /* counter++ */
/* 原子读取 */
int val = atomic_load(&counter);
/* 原子写入 */
atomic_store(&counter, 10);
/* 比较并交换(CAS) */
int expected = 5;
atomic_compare_exchange_strong(&counter, &expected, 10);
/* 如果 counter == 5,设为 10,返回 true */
/* 否则 expected = counter,返回 false */
无锁计数器
#include <stdatomic.h>
#include <threads.h>
atomic_int counter = 0;
int increment(void *arg)
{
for (int i = 0; i < 1000000; i++) {
atomic_fetch_add(&counter, 1);
}
return 0;
}
int main(void)
{
thrd_t t1, t2;
thrd_create(&t1, increment, NULL);
thrd_create(&t2, increment, NULL);
thrd_join(t1, NULL);
thrd_join(t2, NULL);
printf("Counter: %d\n", atomic_load(&counter)); /* 2000000 */
return 0;
}
内存序
/* 内存序控制 */
atomic_store_explicit(&flag, 1, memory_order_release);
atomic_load_explicit(&flag, memory_order_acquire);
/* 内存序类型 */
memory_order_relaxed; /* 无同步 */
memory_order_consume; /* 消费 */
memory_order_acquire; /* 获取 */
memory_order_release; /* 释放 */
memory_order_acq_rel; /* 获取-释放 */
memory_order_seq_cst; /* 顺序一致(默认) */
原子标志
atomic_flag lock = ATOMIC_FLAG_INIT;
/* 自旋锁 */
while (atomic_flag_test_and_set(&lock)) {
/* 等待 */
}
/* 临界区 */
atomic_flag_clear(&lock);
兼容性
#ifdef __STDC_NO_ATOMICS__
/* 编译器不支持原子操作 */
/* 使用互斥锁替代 */
#else
#include <stdatomic.h>
#endif
常见错误
非原子访问原子变量:
atomic_int counter;
counter++; /* 错误:非原子操作 */
/* 正确 */
atomic_fetch_add(&counter, 1);
ABA 问题:
/* CAS 的经典问题:值从 A→B→A,CAS 认为未改变 */
/* 解决方案:使用带版本号的指针 */
最佳实践
- 共享可变数据用原子类型
- 简单计数器用
atomic_fetch_add - 复杂操作仍用互斥锁
- 理解内存序对性能的影响
- 无锁算法需要深入理解内存模型