Debian上Rust并发编程技巧
在Debian上使用Rust进行并发编程前,需先安装Rust工具链。通过curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh命令安装rustup,安装完成后运行source $HOME/.cargo/env配置环境变量,确保rustc、cargo等命令可用。
Rust的std::thread模块支持创建操作系统级线程,通过所有权转移和线程安全类型避免数据竞争:
Arc+Mutex组合:Arc(原子引用计数)用于跨线程共享所有权,Mutex(互斥锁)确保同一时间只有一个线程访问数据。例如,多线程计数器场景中,用Arc<Mutex<u32>>包装计数器,通过lock()方法获取锁并修改数据,join()等待所有线程完成。use std::sync::{Arc, Mutex};
use std::thread;
fn main() {
let counter = Arc::new(Mutex::new(0));
let mut handles = vec![];
for _ in 0..10 {
let counter = Arc::clone(&counter);
let handle = thread::spawn(move || {
let mut num = counter.lock().unwrap();
*num += 1;
});
handles.push(handle);
}
for handle in handles { handle.join().unwrap(); }
println!("Result: {}", *counter.lock().unwrap());
}
Rust推荐使用消息传递(Channels)替代共享内存,通过std::sync::mpsc模块实现多生产者单消费者(MPSC)通信。发送方(tx)和接收方(rx)通过通道传递数据,无需手动同步:
use std::sync::mpsc;
use std::thread;
fn main() {
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
let val = String::from("Hello from thread!");
tx.send(val).unwrap(); // 发送数据到通道
});
let received = rx.recv().unwrap(); // 接收数据
println!("Got: {}", received);
}
Rust的异步编程模型基于async/await语法和tokio运行时,适用于高并发I/O场景(如网络服务)。通过tokio::spawn创建异步任务,tokio::select!并发等待多个任务:
tokio = { version = "1", features = ["full"] }到Cargo.toml,使用#[tokio::main]宏启动异步运行时。tokio::spawn启动多个异步任务,await等待所有任务完成。tokio::sync::Mutex用于异步任务间的数据共享,不会阻塞线程。use tokio::sync::Mutex;
use std::sync::Arc;
use tokio::time::{sleep, Duration};
async fn increment(counter: Arc<Mutex<i32>>) {
let mut counter = counter.lock().await;
*counter += 1;
}
#[tokio::main]
async fn main() {
let counter = Arc::new(Mutex::new(0));
let handles: Vec<_> = (0..10).map(|_| {
let counter = Arc::clone(&counter);
tokio::spawn(async move { increment(counter).await; })
}).collect();
for handle in handles { handle.await.unwrap(); }
println!("Counter: {}", *counter.lock().await);
}
std::sync::atomic模块的原子类型(如AtomicUsize),避免锁的开销。例如,自旋锁实现:use std::sync::atomic::{AtomicBool, Ordering};
use std::thread;
struct SpinLock { locked: AtomicBool }
impl SpinLock {
fn new() -> Self { SpinLock { locked: AtomicBool::new(false) } }
fn lock(&self) {
while self.locked.compare_exchange_weak(false, true, Ordering::Acquire, Ordering::Relaxed).is_err() {}
}
fn unlock(&self) { self.locked.store(false, Ordering::Release); }
}
rayon库简化并行迭代,自动管理线程池。例如,并行遍历数组:use rayon::prelude::*;
fn main() {
let sum: i32 = (1..100).into_par_iter().sum();
println!("Sum: {}", sum);
}
tokio::select!:并发等待多个异步任务,提升响应速度。例如,同时等待网络请求和定时器:use tokio::time::{sleep, Duration};
#[tokio::main]
async fn main() {
tokio::select! {
_ = sleep(Duration::from_secs(1)) => println!("Timeout"),
_ = async { println!("Task completed"); } => println!("Task done"),
}
}
Arc<Mutex>或原子类型)。mpsc通道而非共享内存,降低同步复杂度。Mutex,异步场景用tokio::sync::Mutex;高频操作考虑无锁数据结构。Send、Sync等trait约束,让编译器捕获并发错误。