Rust原子类型

Rust 中的原子类型(Atomic Types)定义在 std::sync::atomic 模块中,它们用于在多线程环境下安全地共享和修改数据,而无需使用重量级的锁(如 Mutex)。原子操作是无锁的(Lock-free),通常速度更快,是构建其他并发原语的基础。

1. 核心原子类型

Rust 提供了多种基本类型的原子版本,常用的包括:
  • 整数原子:AtomicU8, AtomicU16, AtomicU32, AtomicU64, AtomicUsize(无符号)
  • 有符号整数原子:AtomicI8, AtomicI16, AtomicI32, AtomicI64, AtomicIsize
  • 布尔原子:AtomicBool
  • 指针原子:AtomicPtr<T>
关于 AtomicU16
AtomicU16 是一种专门用于安全共享 16 位无符号整数的原子类型,内存布局与普通的 u16 相同。可以在不需要 mut 关键字的情况下修改原子类型的值(利用了内部可变性)。

2. 原子类型常用方法 

原子类型提供了一系列原子的(不可中断的)操作方法:
  • new(v): 创建一个新值。
  • load(&self, Ordering): 原子地读取当前值。
  • store(&self, val, Ordering): 原子地写入新值。
  • swap(&self, val, Ordering): 原子地写入新值并返回旧值。
  • compare_exchange / compare_and_swap: 比较并交换值 (CAS)。
  • fetch_add / fetch_sub: 原子地加/减。
  • fetch_and / fetch_or / fetch_xor: 原子地位操作。 [3, 10]

3. 原子操作的核心:内存排序 (Ordering)

每个原子操作都需要一个 Ordering 参数,它决定了并发环境下指令执行的顺序和内存可见性:
  • Ordering::Relaxed: 仅保证操作本身是原子的,没有保证顺序,性能最好。
  • Ordering::Acquire: 用于读取,保证在这个读取之后的操作不会被重排序到这个读取之前。
  • Ordering::Release: 用于写入,保证在这个写入之前的操作不会被重排序到这个写入之后。
  • Ordering::AcqRel: 同时包含 Acquire 和 Release。
  • Ordering::SeqCst: 顺序一致性,最强,所有线程看到的操作顺序是一致的。

4. AtomicU16 使用示例

use std::sync::atomic::{AtomicU16, Ordering};
use std::sync::Arc;
use std::thread;

fn main() {
    // 1. 创建 AtomicU16
    let atom_u16 = Arc::new(AtomicU16::new(100));

    let mut handles = vec![];
    for _ in 0..10 {
        let atom_clone = Arc::clone(&atom_u16);
        let handle = thread::spawn(move || {
            // 2. 原子加法 (fetch_add)
            // 即使多个线程同时操作,也能保证数值正确
            atom_clone.fetch_add(1, Ordering::SeqCst);
        });
        handles.push(handle);
    }

    for handle in handles {
        handle.join().unwrap();
    }

    // 3. 读取原子值 (load)
    let final_val = atom_u16.load(Ordering::SeqCst);
    println!("Final value: {}", final_val); // 输出:Final value: 110
}

5. 原子类型与普通类型的区别

特性普通类型 (如 u16)原子类型 (如 AtomicU16)
线程安全 默认不可多线程写 Sync,安全地跨线程共享
修改 需要 &mut 不需要 &mut (支持内部可变性)
原子性 可能跨越多个指令 操作是不可中断的
通常需要锁 不需要锁,CAS 机制
性能 极快 较快,取决于 CAS 冲突情况

6. 注意事项

  • 原子类型并不总是比 Mutex 快。如果争用非常激烈(许多线程同时频繁修改同一个原子变量),CAS 循环(如 fetch_add 的底层实现)可能比锁导致更严重的 CPU 损耗。
  • 并不是所有平台都支持 128 位原子操作。
  • 使用 Ordering::Relaxed 可以获得最高性能,但必须确保你的算法即使在弱顺序下也是正确的。
 
posted @ 2026-04-10 10:50  PKICA  阅读(23)  评论(0)    收藏  举报