原子操作是并发编程中的一个核心概念。让我详细解释什么是原子操作原子操作是指在执行过程中不会被中断的操作要么完全执行要么完全不执行不会出现部分执行的状态。比喻理解就像原子是不可分割的基本单位一样原子操作是不可分割的操作单位。非原子操作的问题先看一个非原子操作的例子123456intcounter 0;// 这不是原子操作voidincrement() {counter counter 1;}在汇编层面这通常分为三步123mov eax, [counter] ; 1. 读取counter到寄存器inc eax ; 2. 寄存器值加1mov [counter], eax ; 3. 写回内存竞态条件问题线程A读取counter0线程B读取counter0线程A计算011线程B计算011线程A写入counter1线程B写入counter1 ← 结果应该是2但实际是1C语言中的原子操作C11标准引入的原子类型1234567891011121314151617#include stdatomic.h// 声明原子变量atomic_int atomic_counter ATOMIC_VAR_INIT(0);// 原子操作voidincrement_atomic() {atomic_fetch_add(atomic_counter, 1);// 原子加法}intmain() {atomic_counter 5;// 原子存储intvalue atomic_counter;// 原子加载printf(Counter: %d\n, value);return0;}常见的原子操作函数基本操作12345678910111213141516#include stdatomic.hatomic_int counter ATOMIC_VAR_INIT(0);// 加载和存储intload_value atomic_load(counter);// 原子读取atomic_store(counter, 42);// 原子写入// 交换操作intold_value atomic_exchange(counter, 100);// 原子交换// 比较交换CAS - Compare And Swapintexpected 100;if(atomic_compare_exchange_strong(counter, expected, 200)) {printf(CAS成功: 旧值%d, 新值200\n, expected);}算术运算123456789// 原子加法intold atomic_fetch_add(counter, 5);// counter 5返回旧值// 原子减法atomic_fetch_sub(counter, 3);// counter - 3// 原子自增/自减atomic_fetch_add(counter, 1);// counteratomic_fetch_sub(counter, 1);// counter--位运算123456atomic_int flags ATOMIC_VAR_INIT(0);// 原子位操作atomic_fetch_or(flags, 0x01);// flags | 0x01atomic_fetch_and(flags, ~0x01);// flags ~0x01atomic_fetch_xor(flags, 0x03);// flags ^ 0x03原子操作的实际例子1. 无锁计数器12345678910111213141516171819202122232425#include stdatomic.h#include pthread.h#include stdio.hatomic_int counter ATOMIC_VAR_INIT(0);void* worker(void* arg) {for(inti 0; i 100000; i) {atomic_fetch_add(counter, 1);// 原子自增}returnNULL;}intmain() {pthread_t t1, t2;pthread_create(t1, NULL, worker, NULL);pthread_create(t2, NULL, worker, NULL);pthread_join(t1, NULL);pthread_join(t2, NULL);printf(最终计数: %d (应该是200000)\n, atomic_load(counter));return0;}2. 自旋锁实现12345678910111213141516171819#include stdatomic.htypedefatomic_flag spinlock_t;voidspinlock_init(spinlock_t* lock) {atomic_flag_clear(lock);}voidspinlock_lock(spinlock_t* lock) {// 忙等待直到获得锁while(atomic_flag_test_and_set(lock)) {// 可选的减少CPU占用// __builtin_ia32_pause(); // x86的PAUSE指令}}voidspinlock_unlock(spinlock_t* lock) {atomic_flag_clear(lock);}3. 无锁栈Lock-Free Stack1234567891011121314151617181920212223242526272829303132333435363738394041#include stdatomic.h#include stdlib.htypedefstructNode {intdata;structNode* next;} Node;typedefstruct{_Atomic(Node*) top;} LockFreeStack;voidstack_init(LockFreeStack* stack) {atomic_store(stack-top, NULL);}voidstack_push(LockFreeStack* stack,intvalue) {Node* new_node malloc(sizeof(Node));new_node-data value;Node* old_top;do{old_top atomic_load(stack-top);new_node-next old_top;}while(!atomic_compare_exchange_weak(stack-top, old_top, new_node));}intstack_pop(LockFreeStack* stack) {Node* old_top;Node* new_top;do{old_top atomic_load(stack-top);if(old_top NULL)return-1;// 栈空new_top old_top-next;}while(!atomic_compare_exchange_weak(stack-top, old_top, new_top));intvalue old_top-data;free(old_top);returnvalue;}内存顺序Memory Order原子操作还涉及内存可见性问题12345678910111213141516171819#include stdatomic.hatomic_int data ATOMIC_VAR_INIT(0);atomic_int flag ATOMIC_VAR_INIT(0);// 生产者线程voidproducer() {atomic_store_explicit(data, 42, memory_order_relaxed);atomic_store_explicit(flag, 1, memory_order_release);// 释放语义}// 消费者线程voidconsumer() {while(atomic_load_explicit(flag, memory_order_acquire) 0) {// 等待}intvalue atomic_load_explicit(data, memory_order_relaxed);printf(Data: %d\n, value);// 保证看到42}不同平台的原生原子操作x86架构12345678910// 内联汇编实现原子操作intatomic_increment(int* value) {__asm__ __volatile__(lock incl %0// lock前缀确保原子性:m(*value)::cc);return*value;}GCC内置原子操作12345678910intcounter 0;// GCC内置的原子操作voidincrement_gcc() {__sync_fetch_and_add(counter, 1);}intcompare_and_swap_gcc(int* ptr,intoldval,intnewval) {return__sync_val_compare_and_swap(ptr, oldval, newval);}原子操作的优缺点优点高性能避免锁的开销无死锁不会出现锁顺序问题可扩展性在多核系统中表现良好缺点复杂性正确实现很困难ABA问题在CAS操作中可能出现平台依赖性不同硬件支持程度不同