Rust原子操作宏库atomic-macro的使用,提供高效线程安全的原子类型操作与同步原语

use atomig::Atom;

#[derive(Atom)]
enum State {
    A,
    B,
    C,
}

fn main() {
    let state = std::sync::Arc::new(atomig::Atomic::new(State::A));
    
    // 原子操作示例
    let prev = state.swap(State::B, std::sync::atomic::Ordering::SeqCst);
    println!("Previous state: {:?}", prev);
    
    // 比较并交换操作
    let result = state.compare_exchange(
        State::B,
        State::C,
        std::sync::atomic::Ordering::SeqCst,
        std::sync::atomic::Ordering::Relaxed
    );
    println!("CAS result: {:?}", result);
}

完整示例demo:

// 在Cargo.toml中添加依赖
// atomig-macro = "0.4.0"
// atomig = "0.4"

use atomig::Atom;
use std::sync::Arc;
use std::thread;

// 定义原子枚举类型
#[derive(Atom, Debug, PartialEq)]
enum CounterState {
    Idle,
    Counting,
    Completed,
}

fn main() {
    // 创建原子状态
    let state = Arc::new(atomig::Atomic::new(CounterState::Idle));
    
    let mut handles = vec![];

    // 创建多个线程并发操作原子状态
    for i in 0..5 {
        let state_clone = Arc::clone(&state);
        let handle = thread::spawn(move || {
            // 尝试从Idle状态切换到Counting状态
            let result = state_clone.compare_exchange(
                CounterState::Idle,
                CounterState::Counting,
                std::sync::atomic::Ordering::SeqCst,
                std::sync::atomic::Ordering::Relaxed
            );
            
            match result {
                Ok(_) => {
                    println!("Thread {} started counting", i);
                    // 模拟一些工作
                    thread::sleep(std::time::Duration::from_millis(100));
                    // 切换到完成状态
                    state_clone.store(CounterState::Completed, std::sync::atomic::Ordering::SeqCst);
                    println!("Thread {} completed", i);
                }
                Err(current) => {
                    println!("Thread {} found state: {:?}", i, current);
                }
            }
        });
        handles.push(handle);
    }

    // 等待所有线程完成
    for handle in handles {
        handle.join().unwrap();
    }

    // 检查最终状态
    let final_state = state.load(std::sync::atomic::Ordering::SeqCst);
    println!("Final state: {:?}", final_state);
}

这个示例展示了如何使用atomic-macro库创建线程安全的原子枚举类型,并通过多个线程进行并发操作。代码演示了原子比较交换操作、状态存储和加载等常见原子操作模式。


1 回复

Rust原子操作宏库atomic-macro使用指南

概述

atomic-macro是一个提供高效线程安全的原子类型操作与同步原语的Rust宏库。它通过过程宏简化了原子类型的声明和使用,帮助开发者编写更安全的并发代码。

核心功能

  • 自动生成原子类型包装器
  • 提供原子操作的便捷接口
  • 支持多种内存排序策略
  • 简化同步原语的实现

安装方法

在Cargo.toml中添加依赖:

[dependencies]
atomic-macro = "0.1"

基本用法

1. 声明原子类型

use atomic_macro::atomic;

#[atomic]
struct Counter {
    value: i32,
}

fn main() {
    let counter = Counter::new(0);
    
    // 原子递增
    counter.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
    
    // 获取当前值
    let current = counter.load(std::sync::atomic::Ordering::SeqCst);
    println!("Current value: {}", current);
}

2. 自定义原子结构体

#[atomic]
struct AtomicData {
    count: i64,
    flag: bool,
    data: u32,
}

impl AtomicData {
    pub fn increment(&self) {
        self.fetch_update(
            |mut state| {
                state.count += 1;
                Some(state)
            },
            std::sync::atomic::Ordering::SeqCst,
            std::sync::atomic::Ordering::SeqCst,
        );
    }
}

3. 多线程安全操作示例

use std::sync::Arc;
use std::thread;

#[atomic]
struct SharedCounter {
    value: i32,
}

fn main() {
    let counter = Arc::new(SharedCounter::new(0));
    let mut handles = vec![];

    for _ in 0..10 {
        let counter = Arc::clone(&counter);
        handles.push(thread::spawn(move || {
            for _ in 0..1000 {
                counter.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
            }
        }));
    }

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

    println!("Final count: {}", counter.load(std::sync::atomic::Ordering::SeqCst));
}

4. 比较交换操作

#[atomic]
struct AtomicValue {
    data: i32,
}

fn try_update(atomic: &AtomicValue) -> Result<i32, i32> {
    let current = atomic.load(std::sync::atomic::Ordering::SeqCst);
    let new = current + 10;
    
    atomic.compare_exchange(
        current,
        new,
        std::sync::atomic::Ordering::SeqCst,
        std::sync::atomic::Ordering::SeqCst,
    )
}

内存排序选项

支持所有标准的内存排序模式:

  • Relaxed
  • Release
  • Acquire
  • AcqRel
  • SeqCst

注意事项

  1. 确保正确选择内存排序策略以满足线程安全需求
  2. 原子操作虽然线程安全,但仍需注意逻辑正确性
  3. 建议使用SeqCst排序除非有明确的性能优化需求

性能建议

  • 在热点路径中避免不必要的原子操作
  • 根据具体场景选择合适的内存排序
  • 考虑使用更轻量的同步原语如原子布尔值

这个库特别适合需要高性能原子操作的场景,如并发计数器、状态标志、无锁数据结构等。

完整示例demo

use atomic_macro::atomic;
use std::sync::Arc;
use std::thread;

// 声明原子计数器结构体
#[atomic]
struct AtomicCounter {
    count: i32,
}

// 自定义原子数据结构体
#[atomic]
struct AtomicUserData {
    id: u64,
    score: i32,
    active: bool,
}

impl AtomicUserData {
    // 自定义方法:增加分数
    pub fn add_score(&self, points: i32) {
        self.fetch_update(
            |mut state| {
                state.score += points;
                Some(state)
            },
            std::sync::atomic::Ordering::SeqCst,
            std::sync::atomic::Ordering::SeqCst,
        );
    }
    
    // 自定义方法:激活/停用状态切换
    pub fn toggle_active(&self) {
        self.fetch_update(
            |mut state| {
                state.active = !state.active;
                Some(state)
            },
            std::sync::atomic::Ordering::SeqCst,
            std::sync::atomic::Ordering::SeqCst,
        );
    }
}

fn main() {
    // 示例1:基本原子计数器使用
    println!("=== 基本原子计数器示例 ===");
    let counter = AtomicCounter::new(0);
    
    // 原子递增操作
    counter.fetch_add(5, std::sync::atomic::Ordering::SeqCst);
    println!("计数增加5后: {}", counter.load(std::sync::atomic::Ordering::SeqCst));
    
    // 原子递减操作
    counter.fetch_sub(2, std::sync::atomic::Ordering::SeqCst);
    println!("计数减少2后: {}", counter.load(std::sync::atomic::Ordering::SeqCst));

    // 示例2:自定义原子数据结构体使用
    println!("\n=== 自定义原子数据结构体示例 ===");
    let user_data = AtomicUserData::new(AtomicUserData { 
        id: 1001, 
        score: 0, 
        active: false 
    });
    
    // 使用自定义方法增加分数
    user_data.add_score(10);
    user_data.add_score(5);
    
    // 切换激活状态
    user_data.toggle_active();
    
    // 读取当前状态
    let current_state = user_data.load(std::sync::atomic::Ordering::SeqCst);
    println!("用户状态: ID={}, 分数={}, 激活状态={}", 
             current_state.id, current_state.score, current_state.active);

    // 示例3:多线程并发操作
    println!("\n=== 多线程并发操作示例 ===");
    let shared_counter = Arc::new(AtomicCounter::new(0));
    let mut handles = vec![];

    // 创建10个线程,每个线程增加计数100次
    for i in 0..10 {
        let counter_ref = Arc::clone(&shared_counter);
        handles.push(thread::spawn(move || {
            for j in 0..100 {
                counter_ref.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
                // 使用Relaxed排序在非关键路径上提高性能
                if j % 20 == 0 {
                    let current = counter_ref.load(std::sync::atomic::Ordering::Relaxed);
                    println!("线程{}: 当前计数={}", i, current);
                }
            }
        }));
    }

    // 等待所有线程完成
    for handle in handles {
        handle.join().unwrap();
    }

    // 最终结果使用SeqCst确保正确性
    let final_count = shared_counter.load(std::sync::atomic::Ordering::SeqCst);
    println!("最终计数结果: {}", final_count);

    // 示例4:比较交换操作
    println!("\n=== 比较交换操作示例 ===");
    let value = AtomicCounter::new(42);
    
    // 尝试更新值
    match value.compare_exchange(
        42,
        100,
        std::sync::atomic::Ordering::SeqCst,
        std::sync::atomic::Ordering::SeqCst,
    ) {
        Ok(prev) => println!("成功更新,原值: {}", prev),
        Err(current) => println!("更新失败,当前值: {}", current),
    }
    
    // 再次尝试更新(应该失败)
    match value.compare_exchange(
        42,
        200,
        std::sync::atomic::Ordering::SeqCst,
        std::sync::atomic::Ordering::SeqCst,
    ) {
        Ok(prev) => println!("成功更新,原值: {}", prev),
        Err(current) => println!("更新失败,当前值: {}", current),
    }
}

这个完整示例展示了atomic-macro库的主要功能:

  1. 基本原子计数器的声明和使用
  2. 自定义原子数据结构体的实现和方法定义
  3. 多线程环境下的安全并发操作
  4. 比较交换操作的实践应用
  5. 不同内存排序策略的选择和使用

运行此示例将展示原子操作在多线程环境中的线程安全性,以及各种原子操作方法的正确用法。

回到顶部