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
注意事项
- 确保正确选择内存排序策略以满足线程安全需求
- 原子操作虽然线程安全,但仍需注意逻辑正确性
- 建议使用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库的主要功能:
- 基本原子计数器的声明和使用
- 自定义原子数据结构体的实现和方法定义
- 多线程环境下的安全并发操作
- 比较交换操作的实践应用
- 不同内存排序策略的选择和使用
运行此示例将展示原子操作在多线程环境中的线程安全性,以及各种原子操作方法的正确用法。